Apex 提供了 关键字 final, instanceof, super, this, transient, with sharing and without sharing
- 使用 final 关键字
- 使用 instanceof 关键字
- 使用 super 关键字
- 使用 this 关键字
- 使用 transient 关键字
- 使用 with sharing、without sharing 和 inherited sharing 关键字 在类上使用 or 关键字
指定是否必须强制执行共享规则。在类上使用关键字,以在调用该类的类的共享模式下运行该类。with sharing without sharing inherited sharing
使用 final 关键字
您可以使用关键字 修改变量。
final
- 最终变量只能赋值一次,无论是在声明变量时还是在 构造函数。您必须在以下两个位置之一为其赋值。
- 静态最终变量可以在静态初始化中更改 代码或定义的位置。
- 成员最终变量可以在初始化代码块中更改, 构造函数,或使用其他变量声明。
- 要定义常量,请将变量标记为 和 。staticfinal
- 非最终静态变量用于在 类级别(例如触发器之间的状态)。然而,事实并非如此 在请求之间共享。
- 默认情况下,方法和类是最终的。不能在声明中使用关键字 的类或方法。这意味着它们不能被覆盖。如果需要覆盖,请使用关键字 方法或类。finalvirtua
使用 instanceof 关键字
如果需要在运行时验证对象是否实际上是 特定类,请使用关键字。 关键字只能用于 验证关键字右侧表达式中的目标类型是否可行 左侧表达式的声明类型的替代项。instanceofinstanceof您可以将以下检查添加到类中的类中,然后 将项目投射回对象之前的投射示例。
ReportCustomReport
If (Reports.get(0) instanceof CustomReport) {
// Can safely cast it back to a custom report object
CustomReport c = (CustomReport) Reports.get(0);
} Else {
// Do something with the non-custom-report.
}
注意
在使用 API 版本 32.0 及更高版本保存的 Apex 中,如果左操作数为 null 对象,则返回。为 示例,以下示例返回 。instanceoffalsefalse
Object o = null;
Boolean result = o instanceof Account;
System.assertEquals(false, result);
在 API 版本 31.0 及更早版本中,在本例中返回。instanceoftrue
使用 super 关键字
关键字可以 由从虚拟类或抽象类扩展而来的类使用。 通过使用 ,可以覆盖 父类中的构造函数和方法。supersuper例如,如果您有以下虚拟类:
public virtual class SuperClass {
public String mySalutation;
public String myFirstName;
public String myLastName;
public SuperClass() {
mySalutation = 'Mr.';
myFirstName = 'Carl';
myLastName = 'Vonderburg';
}
public SuperClass(String salutation, String firstName, String lastName) {
mySalutation = salutation;
myFirstName = firstName;
myLastName = lastName;
}
public virtual void printName() {
System.debug('My name is ' + mySalutation + myLastName);
}
public virtual String getFirstName() {
return myFirstName;
}
}
您可以创建以下类来扩展和重写其方法:
SuperclassprintName
public class Subclass extends Superclass {
public override void printName() {
super.printName();
System.debug('But you can call me ' + super.getFirstName());
}
}
调用时的预期输出为Subclass.printNameMy name is Mr. Vonderburg. But you can call me Carl.还可以用于调用构造函数。将以下构造函数添加到:
superSubClass
public Subclass() {
super('Madam', 'Brenda', 'Clapentrap');
}
现在,预期的输出是Subclass.printNameMy name is Madam Clapentrap. But you can call me Brenda.
使用 super 关键字的最佳做法
- 只有扩展自 或 类的类才能使用 .virtualabstractsuper
- 只能在用关键字指定的方法中使用。superoverride
使用 this 关键字
有两种不同的使用关键字的方法。this
您可以使用关键字 以点表示法,不带括号,表示当前实例 它出现在哪个类中。使用这种形式的关键字来访问实例变量 和方法。例如:thisthis
public class myTestThis {
string s;
{
this.s = 'TestString';
}
}
在上面的示例中,该类声明了一个实例变量。初始化代码填充 使用 关键字的变量。myTestThissthis
或者你可以使用关键字来做构造函数链接,即在一个构造函数中, 调用另一个构造函数。在此格式中,使用带括号的关键字。为 例:thisthis
public class testThis {
// First constructor for the class. It requires a string parameter.
public testThis(string s2) {
}
// Second constructor for the class. It does not require a parameter.
// This constructor calls the first constructor using the this keyword.
public testThis() {
this('None');
}
}
当您使用关键字时 在构造函数中,要执行构造函数链接,它必须是第一个 语句。this
使用 transient 关键字
使用关键字声明实例 无法保存且不应作为视图状态的一部分传输的变量 用于 Visualforce 页面。为 例:
transient
Transient Integer currentTotal;
您还可以在 Apex 中使用关键字 可序列化的类,即在控制器、控制器扩展或类中 实现 or 接口。此外,还可以在定义类型的类中使用 在可序列化类中声明的字段。transientBatchableSchedulabletransient
将变量声明为缩减视图 状态大小。关键字的一个常见用例是 Visualforce 页面上的字段,该字段仅在页面持续时间内需要 请求,但不应是页面视图状态的一部分,并且会使用过多的系统 在请求期间要多次重新计算的资源。transienttransient
某些 Apex 对象会自动被视为瞬态对象,也就是说,它们的值不会 保存为页面视图状态的一部分。这些对象包括:
- 页面引用
- XmlStream 类
- 集合自动标记为暂时性,仅当它们的对象类型 保留会自动标记为暂时性保留,例如保存点的集合
- 大多数对象由系统方法生成,例如 .Schema.getGlobalDescribe
- JSONParser类实例。
静态变量也不会得到 通过视图状态传输。
以下示例包含一个 Visualforce 页面和一个自定义控制器。点击 页面上的“刷新”按钮使瞬态日期为 已更新,因为每次刷新页面时都会重新创建它。非瞬态 date 继续具有其原始值,该值已从视图中反序列化 状态,所以它保持不变。
<apex:page controller="ExampleController">
T1: {!t1} <br/>
T2: {!t2} <br/>
<apex:form>
<apex:commandLink value="refresh"/>
</apex:form>
</apex:page>
public class ExampleController {
DateTime t1;
transient DateTime t2;
public String getT1() {
if (t1 == null) t1 = System.now();
return '' + t1;
}
public String getT2() {
if (t2 == null) t2 = System.now();
return '' + t2;
}
}
使用有共享、无共享和继承共享关键字
在类上使用 or 关键字来指定是否 必须强制执行共享规则。在类上使用关键字以在类的共享模式下运行该类 称其为。
with sharingwithout sharinginherited sharing
与共享
在声明 类来强制执行当前用户的共享规则。显式设置此关键字可确保 Apex 代码在当前用户上下文中运行。通过调用执行的 Apex 代码和 Apex 中的 Connect 始终执行 使用当前用户的共享规则。有关 的详细信息,请参阅匿名块。with sharingexecuteAnonymousexecuteAnonymous
在声明 类来强制执行适用于当前用户的共享规则。例如:with sharing
public with sharing class sharingClass {
// Code here
}
无共享
在声明 类来确保不强制执行当前用户的共享规则。例如 当一个类从另一个类调用时,您可以显式关闭共享规则强制执行 使用 声明的类。without sharingwith sharing
public without sharing class noSharing {
// Code here
}
继承共享
在声明 类来强制执行调用它的类的共享规则。使用是一种先进的技术来确定 运行时的共享模式,并设计可以在任一模式下运行的 Apex 类。inherited sharinginherited sharingwith sharingwithout sharing
警告
由于共享模式是在运行时确定的,因此必须采取极端措施 注意确保您的 Apex 代码可以安全地在两种模式下运行。with sharingwithout sharing将 一起使用 和其他 适当的安全检查,有助于通过 AppExchange 安全审查并确保 您的特权 Apex 代码不会以意外或不安全的方式使用。一个 Apex 类,其运行方式为:
inherited sharinginherited sharingwith sharing
- Aura 组件控制器
- Visualforce 控制器
- Apex REST 服务
- Apex 事务的任何其他入口点
标有 Apex 类和省略共享的类之间有明显的区别 声明。如果该类用作 Apex 事务的入口点,则省略 共享声明以 . 但是,确保默认 是以 .声明为 的类仅在从 已经建立的上下文。inherited sharingwithout sharinginherited sharingwith sharinginherited sharingwithout sharingwithout sharing
例
此示例声明一个 Apex 类,其中包含该 Apex 代码的 Visualforce 调用。由于声明,只有联系人 显示正在运行的用户具有共享访问权限。如果省略声明,请联系 由于不安全的默认值,用户没有查看权限 行为。
inherited sharinginherited sharing
public inherited sharing class InheritedSharingClass {
public List<Contact> getAllTheSecrets() {
return [SELECT Name FROM Contact];
}
}
<apex:page controller="InheritedSharingClass">
<apex:repeat value="{!allTheSecrets}" var="record">
{!record.Name}
</apex:repeat>
</apex:page>
实施细节
- 应用定义方法的类的共享设置,而不是 从中调用方法的类。例如,如果在类中定义了方法 声明为由类调用 声明为 ,方法 在强制执行共享规则的情况下执行。with sharingwithout sharing
- 如果类未显式声明为 either 或 , 当前共享规则仍然有效。因此,该类不强制执行共享 规则,除非它从另一个类获取共享规则。例如,如果 类由另一个强制执行共享的类调用,然后强制执行共享 被调用的类。with sharingwithout sharing
- 内部类和外部类都可以声明为 。内部类不继承 共享容器类中的设置。否则,共享设置将应用于 类中包含的所有代码,包括初始化代码、构造函数和 方法。with sharing
- 当一个类扩展或 实现另一个。
- Apex 触发器不能具有显式共享声明,不能以 .without sharing
最佳实践
默认情况下,没有显式共享声明的 Apex 是不安全的。我们强烈建议 您始终为类指定共享声明。
无论采用何种共享模式,对象级访问和字段级安全性都不是 由 Apex 强制执行。您必须在 您的 SOQL 查询或代码。例如,机制不强制用户访问查看报表和 仪表 板。您必须显式强制执行正在运行的用户的 CRUD(创建、读取、更新、 Delete) 和代码中的字段级安全性。请参阅强制执行对象和字段权限。with sharing
共享模式 | 何时使用 |
---|---|
with sharing | 使用此模式作为默认模式,除非您的用例另有要求。 |
without sharing | 请谨慎使用此模式。确保您不会无意中暴露敏感内容 通常由共享模型隐藏的数据。这种共享机制是 最适合用于向当前授予有针对性地提升共享权限 用户。例如,使用 允许社区用户读取他们原本不会拥有的记录 访问。without sharing |
inherited sharing | 对于必须灵活且支持使用的服务类,请使用此模式 具有不同共享模式的情况,同时也默认为更安全的模式。with sharing |