Apex 就像 Salesforce 的 Java。它使您能够添加数据并与之交互 Lightning 平台持久性层。它使用类、数据类型、变量和 if-else 语句。您可以根据条件使其执行,也可以执行代码块 反复。
- 数据类型和变量
Apex 使用数据类型、变量和相关语言结构,例如枚举、常量、表达式、运算符和赋值语句。 - 控制流语句
Apex 提供 if-else 语句、switch 语句和循环来控制代码执行的流程。语句通常按照它们出现的顺序逐行执行。使用控制流语句,您可以根据特定条件执行 Apex 代码,也可以让代码块重复执行。 - 在 Apex
中使用数据 您可以在 Lightning 平台持久性层中添加数据并与之交互。sObject 数据类型是保存数据对象的主要数据类型。您将使用数据操作语言 (DML) 来处理数据,并使用查询语言来检索数据,例如 () 等。
数据类型和变量
Apex 使用数据类型、变量和相关语言结构,例如枚举、 常量、表达式、运算符和赋值语句。
- 数据类型
在 Apex 中,所有变量和表达式都具有数据类型,例如 sObject、primitive 或 enum。 - 基元数据类型
Apex 使用与 SOAP API 相同的基元数据类型,但在某些情况下使用更高精度的 Decimal 类型。所有基元数据类型都是按值传递的。 - 集合
Apex 中的集合可以是列表、集合或映射。
枚举 枚举是一种抽象数据类型,其值每个值都恰好采用您指定的一组有限标识符中的一个。枚举通常用于定义一组可能的值,否则这些值没有数字顺序。典型的例子包括一张牌的花色,或一年中的特定季节。- 变量 局部变量
使用 Java 样式语法声明。与 Java 一样,可以在单个语句中声明和初始化多个变量。 - 常量 顶点常量
是其值在初始化一次后不会更改的变量。可以使用关键字定义常量。final - 表达式和运算符 表达式是由变量、运算符
和方法调用组成的构造,其计算结果为单个值。 - 赋值语句 赋值语句是将值放入变量的任何语句
。 - 转换
规则 通常,Apex 要求您显式将一种数据类型转换为另一种数据类型。例如,Integer 数据类型的变量不能隐式转换为 String。您必须使用该方法。但是,可以隐式转换一些数据类型,而无需使用方法。string.format
数据类型
在 Apex 中,所有变量和表达式都有一个数据类型,例如 sObject、primitive、 或枚举。
- 基元,例如 Integer、Double、Long、Date、Datetime、String、ID 或 布尔值(请参阅原始数据 类型)
- sObject,可以作为通用 sObject 或特定 sObject,例如 客户、联系人或MyCustomObject__c(请参阅第 4 章中的使用 sObjects。
- 集合,包括:
- 基元、sObjects、用户定义对象、对象的列表(或数组) 从 Apex 类或集合创建(请参阅列表)
- 一组基元(参见 集合)
- 从基元到基元、sObject 或集合的映射(请参阅映射)
- 值的类型化列表,也称为枚举(请参阅枚举)
- 从用户定义的 Apex 类创建的对象(请参阅类、对象和 接口)
- 从系统提供的 Apex 类创建的对象
- Null(对于常量,可以是 分配给任何变量)null
方法可以返回任何列出的类型的值,也可以返回不返回任何值且类型为 无效。
在编译时严格执行类型检查。例如,解析器生成一个 如果为 Integer 类型的对象字段分配了 String 类型的值,则出错。然而 所有编译时异常都作为特定的故障代码返回,并带有行号 和 error 列。有关详细信息,请参阅调试 Apex。
基元数据类型
Apex 使用与 SOAP API 相同的原始数据类型,但精度更高 在某些情况下为十进制类型。所有基元数据类型都是按值传递的。
所有 Apex 变量,无论它们是类成员变量还是方法变量, 初始化为 。确保您 在使用变量之前,请将其初始化为适当的值。例如 将布尔变量初始化为 。nullfalse
Apex 基元数据类型包括:
此外,两种非标准基元数据类型不能用作变量或方法 类型,但确实出现在系统静态方法中:
- 任意类型。静态方法转换 将 AnyType 类型的 sObject 字段设置为标准基元。AnyType 在 Lightning Platform 数据库专门用于字段历史记录跟踪中的 sObject 字段 表。valueOf
- 货币。静态的 方法创建一个 Currency 类型的文本。此方法仅在 SOQL 中使用 和 SOSL 条款进行过滤 sObject 货币字段。您不能在任何其他类型的 顶点。Currency.newInstanceWHERE
有关 AnyType 数据类型的详细信息,请参阅对象中的字段类型 Salesforce 参考。
版本化行为更改
在 API 版本 16 (Summer ’09) 及更高版本中,Apex 使用更高精度的 Decimal 数据 键入某些类型,例如货币。
收集
Apex 中的集合可以是列表、集合或映射。
注意
没有限制 集合可以容纳的项数。但是,有一个一般的限制 堆大小。
- 列表 列表
是元素的有序集合,这些元素通过其索引进行区分。列表元素可以是任何数据类型,包括基元类型、集合、sObjects、用户定义类型和内置 Apex 类型。 - 集合 集合是不包含任何重复项的元素的无序集合
。Set 元素可以是任何数据类型,包括基元类型、集合、sObjects、用户定义类型和内置 Apex 类型。 - 映射 映射
是键值对的集合,其中每个唯一键映射到单个值。键和值可以是任何数据类型,包括基元类型、集合、sObjects、用户定义类型和内置 Apex 类型。 - 通常,参数化类型化 Apex
是一种静态类型的编程语言,这意味着用户必须先指定变量的数据类型,然后才能使用该变量。
列表
列表是元素的有序集合,这些元素按其索引进行区分。 列表元素可以是任何数据类型,包括基元类型、集合、sObjects、 用户定义类型和内置 Apex 类型。
下表是字符串列表的可视化表示形式:
索引 0 | 索引 1 | 索引 2 | 索引 3 | 索引 4 | 索引 5 |
---|---|---|---|---|---|
“红色” | “橙色” | “黄色” | “绿色” | “蓝色” | “紫色” |
列表中第一个元素的索引位置始终为 0。
列表可以包含任何集合,并且可以相互嵌套并成为 多面的。例如,您可以有一个整数集列表列表。一个列表 其中最多可以包含七级嵌套集合,即最多八级 整体水平。
若要声明列表,请使用关键字 followed 基元数据、sObject、嵌套列表、映射或集类型在 <> 个字符以内。 例如:List
// Create an empty list of String
List<String> my_list = new List<String>();
// Create a nested list
List<List<Set<Integer>>> my_list_2 = new List<List<Set<Integer>>>();
若要访问列表中的元素,请使用 Apex 提供的方法。例如:List
List<Integer> myList = new List<Integer>(); // Define a new list
myList.add(47); // Adds a second element of value 47 to the end
// of the list
Integer i = myList.get(0); // Retrieves the element at index 0
myList.set(0, 1); // Adds the integer 1 to the list at index 0
myList.clear(); // Removes all elements from the list
有关更多信息(包括所有支持的方法的完整列表),请参见 List Class。
使用一维数组表示法 列表
使用基元或对象的一维列表时,可以 还可以使用更传统的数组表示法来声明和引用列表元素。为 例如,可以通过以下方式声明基元或对象的一维列表 在数据类型名称后面加上 [] 字符:
String[] colors = new List<String>();
这两个语句等效于前面的语句:
List<String> colors = new String[1];
String[] colors = new String[1];
自 引用一维列表的一个元素,也可以跟在 在方括号中包含元素索引位置的列表。为 例:
colors[0] = 'Green';
甚至 虽然前一个数组的大小 定义为一个元素(括号中的数字),列表是弹性的,可以增长 根据需要,前提是使用该方法添加新元素。例如 您可以向列表中添加两个或多个元素。但是,如果您使用方括号添加 元素,则该列表的行为类似于数组,并且没有弹性,也就是说, 不允许添加比声明的数组更多的元素 大小。Stringnew String[1]Listaddcolors
所有列表都初始化为 。可以使用文字为列表赋值和分配内存 表示法。例如:null
例 | 描述 |
---|---|
List<Integer> ints = new Integer[0]; | 定义大小为零且不带元素的整数列表 |
List<Integer> ints = new Integer[6]; | 定义一个整数列表,其中为六个分配了内存 整数 |
- 列表排序
可以对列表元素进行排序,排序顺序取决于元素的数据类型。
列表排序
您可以对列表元素进行排序,排序顺序取决于 元素。
使用该方法,您可以对 一个列表。对于基元数据类型的元素(如字符串),排序按升序排列。 其他更复杂的数据类型的排序顺序在介绍这些类型的章节中进行了描述 数据类型。List.sort
此示例演示如何对字符串列表进行排序并验证颜色是否在 列表中的升序。
List<String> colors = new List<String>{
'Yellow',
'Red',
'Green'};
colors.sort();
System.assertEquals('Green', colors.get(0));
System.assertEquals('Red', colors.get(1));
System.assertEquals('Yellow', colors.get(2));
对于 Visualforce SelectOption 控件,根据值按升序排序 和标签字段。请参阅下一节,了解用于 选择选项。
的默认排序顺序 选择选项
该方法对 SelectOption 元素进行排序 使用“值”和“标签”字段进行升序排序,并基于此比较序列。
List.sort
- 值字段首先用于排序。
- 如果两个值字段具有相同的值或都为空,则标签字段为 使用。
请注意,禁用的字段不用于排序。
对于文本字段,排序算法使用 Unicode 排序顺序。此外,空字段在前面 排序顺序中的非空字段。
在此示例中,列表包含三个 SelectOption 元素。Two elements, 美国 和墨西哥,具有相同的值字段(‘A’)。该方法根据 label 字段,并将墨西哥置于美国之前,如输出中所示。最后 排序列表中的元素是 Canada,并按其值字段 ‘C’ 排序, 它位于“A”之后。List.sort
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption('A','United States'));
options.add(new SelectOption('C','Canada'));
options.add(new SelectOption('A','Mexico'));
System.debug('Before sorting: ' + options);
options.sort();
System.debug('After sorting: ' + options);
这是 debug 语句的输出。它显示 排序。
DEBUG|Before sorting: (System.SelectOption[value="A", label="United States", disabled="false"],
System.SelectOption[value="C", label="Canada", disabled="false"],
System.SelectOption[value="A", label="Mexico", disabled="false"])
DEBUG|After sorting: (System.SelectOption[value="A", label="Mexico", disabled="false"],
System.SelectOption[value="A", label="United States", disabled="false"],
System.SelectOption[value="C", label="Canada", disabled="false"])
Set
集合是不包含任何重复项的元素的无序集合。设置 元素可以是任何数据类型,包括基元类型、集合、sObjects、用户定义 类型和内置 Apex 类型。
下表表示一组使用城市名称的字符串:
“旧金山” | “纽约” | “巴黎” | “东京” |
集合可以包含可以相互嵌套的集合。例如,您可以 有一组整数集的列表。一个集合最多可以包含七个嵌套级别 其中的集合,即总共最多八个级别。若要声明集合,请使用关键字 followed 按 <> 个字符以内的基元数据类型名称。为 例:
Set
Set<String> myStringSet = new Set<String>();
下面的示例演示如何创建具有两个硬编码字符串值的集合。
// Defines a new set with two elements
Set<String> set1 = new Set<String>{'New York', 'Paris'};
要访问集合中的元素,请使用 Apex 提供的系统方法。例如:
// Define a new set
Set<Integer> mySet = new Set<Integer>();
// Add two elements to the set
mySet.add(1);
mySet.add(3);
// Assert that the set contains the integer value we added
System.assert(mySet.contains(1));
// Remove the integer value from the set
mySet.remove(1);
下面的示例演示如何从另一个集合的元素创建集合。
// Define a new set that contains the
// elements of the set created in the previous example
Set<Integer> mySet2 = new Set<Integer>(mySet);
// Assert that the set size equals 1
// Note: The set from the previous example contains only one value
System.assert(mySet2.size() == 1);
有关更多信息(包括所有受支持的 set 系统方法的完整列表),请参见 Set Class。请注意集合的以下限制:
- 与 Java 不同,Apex 开发人员不需要引用所使用的算法 在其声明中实现集合(例如,或 )。Apex 对所有集合都使用哈希结构。HashSetTreeSet
- 集合是无序集合 – 您不能在 具体索引。您只能遍历设置的元素。
- 集合元素的迭代顺序是确定性的,因此您可以依赖 顺序在每次后续执行相同代码时相同。
Map
映射是键值对的集合,其中每个唯一键映射到单个值。 键和值可以是任何数据类型,包括基元类型、集合、sObjects、用户定义 类型和内置 Apex 类型。
下表显示了国家和货币的地图:
国家/地区 (键) | “美国” | “日本” | “法国” | “英格兰” | “印度” |
货币(值) | “美元” | “日元” | “欧元” | “磅” | “卢比” |
映射键和值可以包含任何集合,并且可以包含嵌套集合。为 例如,您可以将整数映射到映射,而映射又将字符串映射到列表。地图 键最多可以包含七级嵌套集合,即最多八级 整体。
要声明映射,请使用关键字后跟 键的数据类型和字符内的值。例如:Map<>
Map<String, String> country_currencies = new Map<String, String>();
Map<ID, Set<String>> m = new Map<ID, Set<String>>();
可以将泛型或特定 sObject 数据类型用于映射。您还可以创建一个 映射的泛型实例。
与列表一样,在使用 curly 声明映射时,可以填充映射键值对 brace () 语法。在大括号内,指定 首先,然后使用 指定该键的值。例如:{}=>
Map<String, String> MyStrings = new Map<String, String>{'a' => 'b', 'c' => 'd'.toUpperCase()};
在第一个示例中,键的值是 ,键的值是 。abcD
若要访问地图中的元素,请使用 Apex 提供的 Map 方法。此示例创建一个地图 整数键和字符串值。它添加两个条目,检查第一个条目是否存在 key,检索第二个条目的值,最后获取所有键的集合。
Map<Integer, String> m = new Map<Integer, String>(); // Define a new map
m.put(1, 'First entry'); // Insert a new key-value pair in the map
m.put(2, 'Second entry'); // Insert a new key-value pair in the map
System.assert(m.containsKey(1)); // Assert that the map contains a key
String value = m.get(2); // Retrieve a value, given a particular key
System.assertEquals('Second entry', value);
Set<Integer> s = m.keySet(); // Return a set that contains all of the keys in the map
有关详细信息(包括所有受支持的 Map 方法的完整列表),请参阅 Map 类。
Map注意事项
- 与 Java 不同,Apex 开发人员不需要引用用于 在其声明中实现映射(例如,或 )。Apex 使用哈希 所有地图的结构。HashMapTreeMap
- 映射元素的迭代顺序是确定性的。您可以信赖订单 在每次后续执行相同的代码时都是一样的。但是,我们建议始终 按键访问地图元素。
- 映射键可以保存该值。null
- 添加一个映射条目,其键与映射中的现有键匹配,会覆盖 现有条目,该键具有新条目。
- String 类型的映射键区分大小写。仅因大小写而异的两个键是 被认为是唯一的,并具有相应的不同映射条目。随后,地图 方法,包括 、 、 和 处理这些键 作为不同的。putgetcontainsKeyremove
- 用户定义类型的映射键的唯一性由您在你的班级。所有其他非基元类型的键的唯一性,例如 sObject 键, 通过比较对象的字段值来确定。
- 仅当 Map 对象使用以下数据类型之一时,它才可序列化为 JSON 作为钥匙。
- 布尔
- 日期
- 日期时间
- 十进制
- 双
- 枚举
- 同上
- 整数
- 长
- 字符串
- 时间
参数化类型化
一般来说,Apex 是一种静态类型的编程语言,这意味着用户必须 在使用变量之前,指定该变量的数据类型。这在 Apex 中是合法的:
Integer x = 1;
如果尚未定义,这是不合法的 早些时候:
x
x = 1;
列表、地图和集合在 Apex 中参数化:它们采用任何数据类型 Apex 支持它们作为论据。该数据类型必须替换为实际数据 在构建列表、地图或集时键入。为 例:
List<String> myList = new List<String>();
使用参数化列表进行子类型化
在 Apex 中,如果 type 是 的子类型,则将是 的子类型。例如,以下是 法律:
TUList<T>List<U>
List<String> slst = new List<String> {'alpha', 'beta'};
List<Object> olst = slst;
枚举
枚举是一种抽象数据类型,其值每个值都恰好采用 您指定的有限标识符集。枚举通常用于定义一组 否则没有数字顺序的可能值。典型的例子包括 一张牌的花色,或一年中的特定季节。
尽管每个值对应于一个不同的整数值,但枚举会隐藏此值 实现。隐藏实现可防止任何可能滥用的值 执行算术等。创建枚举、变量、方法参数和 可以声明该类型的返回类型。
注意
与 Java 不同,枚举类型本身没有构造函数语法。
要定义枚举,请在 声明并使用大括号来划分可能值的列表。例如 以下代码创建一个名为 :enumSeason
public enum Season {WINTER, SPRING, SUMMER, FALL}
通过创建枚举,您还可以 创建了一个名为 的新数据类型。您可以 像使用任何其他数据类型一样使用此新数据类型。例如:SeasonSeason
Season southernHemisphereSeason = Season.WINTER;
public Season getSouthernHemisphereSeason(Season northernHemisphereSeason) {
if (northernHemisphereSeason == Season.SUMMER) return southernHemisphereSeason;
//...
}
还可以将类定义为枚举。创建枚举类时,请勿在定义中使用关键字。class
public enum MyEnumClass { X, Y }
您可以在任何可以使用其他数据类型名称的地方使用枚举。如果将 类型为枚举的变量,分配给它的任何对象都必须是该枚举的实例 枚举类。
任何方法都可以使用枚举类型作为一部分 他们的签名。在这种情况下,关联的 WSDL 文件包括 枚举及其值,API 客户端可以使用。webservice
Apex 提供以下系统定义的枚举:
- System.StatusCode这 枚举对应于 WSDL 文档中公开的 API 错误代码 所有 API 操作。为 例:
StatusCode.CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY StatusCode.INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY
完整的 状态代码列表在组织的 WSDL 文件中可用。为 有关访问组织的 WSDL 文件的更多信息,请参阅下载 Salesforce WSDL 和客户端身份验证 Salesforce 帮助中的证书。 - System.XmlTag:此枚举返回用于分析方法的结果 XML 的 XML 标记列表。查看更多 信息,请参见 XmlStreamReader 类。webservice
- System.ApplicationReadWriteMode: 此枚举指示组织在 Salesforce 升级和停机时间。有关更多信息,请参见 System.getApplicationReadWriteMode()。
- System.LoggingLevel:此枚举与方法一起使用,以指定所有调用的日志级别。有关更多信息,请参见 System 类。system.debugdebug
- System.RoundingMode:此枚举由执行数学运算的方法用于指定 操作的舍入行为。典型的例子是 Decimal 方法和 Double 方法。欲了解更多信息, 请参阅舍入模式。divideround
- System.SoapType:此枚举由字段 describe result 方法返回。欲了解更多信息, 请参阅 SOAPType 枚举。getSoapType
- System.DisplayType:此枚举由字段 describe result 方法返回。有关更多信息,请参见 DisplayType 枚举。getType
- System.JSONToken:此枚举用于解析 JSON 内容。有关更多信息,请参见 JsonToken 枚举。
- ApexPages.Severity:此枚举指定 Visualforce 消息的严重性。查看更多 信息,请参阅 ApexPages.Severity 枚举。
- Dom.XmlNodeType:此枚举指定 DOM 文档中的节点类型。
注意
所有枚举值(包括系统枚举)都具有与之关联的通用方法。为 有关详细信息,请参阅枚举方法。
不能将用户定义的方法添加到枚举值。
变量
局部变量是用 Java 样式语法声明的。与 Java 一样,多个变量 可以在单个语句中声明和初始化。
局部变量是用 Java 样式语法声明的。例如:
Integer i = 0;
String str;
List<String> strList;
Set<String> s;
Map<ID, String> m;
与 Java 一样,可以在单个语句中声明和初始化多个变量, 使用逗号分隔。例如:
Integer i, j, k;
Null 变量和初始值
如果您声明一个变量并且不使用值对其进行初始化,则它将是 .从本质上讲,意味着没有值。您还可以分配给使用基元声明的任何变量 类型。例如,这两个语句都会导致变量设置为:
nullnullnullnull
Boolean x = null;
Decimal d;
如果变量为 ,则数据类型上的许多实例方法将失败。在此示例中,第二个语句 生成异常 (
nullNullPointerException)
Date d;
d.addDays(2);
所有变量都初始化为 if 没有为它们分配值。例如,在以下示例中,和 是赋值,而整数变量和布尔变量设置为 ,因为它们未显式初始化。nullikjbnull
Integer i = 0, j, k = 1;
Boolean b;
注意
一个常见的陷阱是假设未初始化的布尔变量是 由系统初始化。这 事实并非如此。与所有其他变量一样,布尔变量如果不是,则为 null 显式分配一个值。false
可变范围
变量可以在块中的任何点定义,并从该点开始 向前。子块无法重新定义已使用的变量名称 在父块中,但并行块可以重用变量名称。例如:
Integer i;
{
// Integer i; This declaration is not allowed
}
for (Integer j = 0; j < 10; j++);
for (Integer j = 0; j < 10; j++);
区分大小写
避免与不区分大小写的 SOQL 混淆 和 SOSL 查询,Apex 也不区分大小写。这意味着:
- 变量和方法名称不区分大小写。为 例:
Integer I; //Integer i; This would be an error.
- 对对象和字段名称的引用不区分大小写。为 例:
Account a1; ACCOUNT a2;
- SOQL 和 SOSL 语句不区分大小写。为 例:
Account[] accts = [sELect ID From ACCouNT where nAme = 'fred'];
注意
稍后您将了解有关 sObjects、SOQL 和 SOSL 的更多信息 指导。
另请注意,Apex 使用与 SOQL 相同的过滤语义,即 是 SOAP API 和 Salesforce 用户界面中比较的基础。这 使用这些语义可能会导致一些有趣的行为。例如,如果 最终用户根据筛选器生成报告,以筛选 字母表(即值< ‘m’),结果中返回 null 字段。这 此行为的基本原理是,用户通常会想到没有值的字段 只是一个空格字符,而不是它的实际值。因此,在 Apex 中,以下表达式全部 计算结果为:nulltrue
String s;
System.assert('a' == 'A');
System.assert(s < 'b');
System.assert(!(s > 'b'));
注意
尽管在上面的示例中计算为 ,但会生成错误,因为 您正在尝试将字母与值进行比较。s < ‘b’true‘b.’compareTo(s)null
常数
顶点常量是其值在初始化后不会更改的变量 一次。可以使用关键字定义常量。
final
关键字表示变量可以是 最多分配一次,可以在声明本身中使用,也可以使用静态初始值设定项 方法,如果常量是在类中定义的。此示例声明两个常量。这 首先在声明语句中初始化。第二个在 static 块,通过调用 static 方法。final
public class myCls {
static final Integer PRIVATE_INT_CONST = 200;
static final Integer PRIVATE_INT_CONST2;
public static Integer calculate() {
return 2 + 7;
}
static {
PRIVATE_INT_CONST2 = calculate();
}
}