控制流语句
Apex 提供 if-else 条件语句、switch 分支语句和五种循环来控制代码的执行流程。默认情况下,语句按出现顺序逐行执行。通过控制流语句,你可以让 Apex 代码根据特定条件执行,或者让一段代码重复执行。
控制流程概览
- 条件语句:if-else(基于 Boolean 条件执行,else 始终与最近的 if 配对)
- Switch 语句:测试表达式是否匹配多个值之一并分支——支持 Integer、Long、sObject、String、Enum。无穿透(fall-through),匹配后立即退出
- 五种循环:do-while(始终至少执行一次)、while(可能零次)、传统 for(初始化→条件→执行→增量五步)、列表/集合迭代 for、SOQL for
- 循环控制:
break;立即退出整个循环、continue;跳到下一次迭代
条件语句 (If-Else)
Apex 中的条件语句与 Java 工作方式相同。每个 if 语句评估一个 Boolean 条件,为 true 时执行第一个代码块,否则执行 else 代码块。else 部分始终是可选的,且始终与最近的 if 配对。
if ([Boolean_condition])
// Statement 1
else
// Statement 2
关键规则:条件必须求值为 Boolean 值。else 始终与最近的 if 配对。单条语句不需要花括号,多语句代码块必须使用花括号 { }。可以使用 else if 链接多个条件进行复杂决策。
// 符号检测示例
Integer x, sign;
if (x >= 0) {
sign = 1;
} else {
sign = -1;
}
// 多条件链式判断
if (score >= 90) {
grade = 'A';
} else if (score >= 80) {
grade = 'B';
} else if (score >= 70) {
grade = 'C';
} else {
grade = 'F';
}
Switch 语句
Apex 提供 switch 语句来测试表达式是否匹配多个值之一并相应地分支。Switch 语句评估表达式并执行匹配 when 值的代码块。如果没有值匹配,则执行 when else 代码块(如果不存在 when else 块则不执行任何操作)。
重要:Apex switch 没有 fall-through(穿透)!执行完匹配的代码块后,switch 语句直接退出。这与 Java 的 switch 行为完全不同。Switch 表达式支持的类型:Integer、Long、sObject、String、Enum。
switch on expression {
when value1 {
// 代码块 1
}
when value2, value3 {
// 代码块 2(多个值可以合并)
}
when TypeName variableName {
// sObject 类型匹配(含隐式 instanceof 检查和类型转换)
}
when else {
// 默认代码块(可选,但强烈推荐)
}
}
When 块详解
每个 when 块有一个与表达式匹配的值。这些值可以采用以下三种形式:
- when 字面量:
when 2 {}或when 2, 3, 4 {}——一个 when 块可以有多个逗号分隔的字面量子句。因为 Apex switch 没有穿透,多个字面量是在一个块中处理多个值的方式。你也可以嵌套 switch 语句在 when 子句中提供多个执行路径 - when sObject 类型:
when Account a {}——隐式执行 instanceof 检查和类型转换,替换冗长的 if-else instanceof 链 - when 枚举值:
when WINTER {}
null 是所有类型的合法 when 值。每个 when 值必须唯一——一个字面量只能出现在一个 when 块子句中。每个 when 块最多匹配一次。String 子句区分大小写('orange' 和 'ORANGE' 是不同的值)。
When Else 块
如果没有 when 值匹配表达式,when else 代码块被执行。虽然 when else 不是必需的,但 Salesforce 强烈建议始终包含它——尤其在以下场景中:
- 枚举类型:使用托管包提供的枚举值时,如果新版本的包包含额外的枚举值,缺少 when else 的代码可能出现意外行为
- 未来兼容性:when else 块作为防御性编程,捕获未预料到的值
如果包含 when else 块,它必须是 switch 语句中的最后一个块。
Switch 示例:字面量、Null 与多值
单值示例(整数字面量):
switch on i {
when 2 {
System.debug('when block 2');
}
when -3 {
System.debug('when block -3');
}
when else {
System.debug('default');
}
}
Null 值示例:因为 Apex 中所有类型都可为 null:
switch on i {
when 2 {
System.debug('when block 2');
}
when null {
System.debug('bad integer');
}
when else {
System.debug('default ' + i);
}
}
多值示例:when 子句可以包含多个逗号分隔的字面量值:
switch on i {
when 2, 3, 4 {
System.debug('when block 2 and 3 and 4');
}
when 5, 6 {
System.debug('when block 5 and 6');
}
when 7 {
System.debug('when block 7');
}
when else {
System.debug('default');
}
}
方法调用示例:可以基于方法调用的返回值进行 switch:
switch on someInteger(i) {
when 2 {
System.debug('when block 2');
}
when 3 {
System.debug('when block 3');
}
when else {
System.debug('default');
}
}
Switch 示例:sObject 类型匹配
在 sObject 值上使用 switch 可以隐式执行 instanceof 检查和类型转换。对比原有的冗长 if-else instanceof 模式:
// 传统 if-else instanceof 写法(冗长)
if (sobject instanceof Account) {
Account a = (Account) sobject;
System.debug('account ' + a);
} else if (sobject instanceof Contact) {
Contact c = (Contact) sobject;
System.debug('contact ' + c);
} else {
System.debug('default');
}
// 使用 switch 简化(完全等价)
switch on sobject {
when Account a {
System.debug('account ' + a);
}
when Contact c {
System.debug('contact ' + c);
}
when null {
System.debug('null');
}
when else {
System.debug('default');
}
}
每个 when 块只能使用一种 sObject 类型。
Switch 示例:枚举
使用枚举 when 值的 switch 语句不需要 when else 块,但强烈推荐包含。可以在每个 when 块子句中使用多个枚举值:
switch on season {
when WINTER {
System.debug('boots');
}
when SPRING, SUMMER {
System.debug('sandals');
}
when else {
System.debug('none of the above');
}
}
循环
Apex 支持五种过程式循环。所有循环都支持循环控制结构:break; 退出整个循环,continue; 跳到下一次迭代。五种循环类型:do-while、while、传统 for、列表/集合迭代 for、SOQL for。
Do-While 循环
do-while 循环在 Boolean 条件为 true 时重复执行代码块:
do {
code_block
} while (condition);
- 花括号 始终是必需的(即使只有一条语句)
- Boolean 条件在第一次循环执行之后才检查。因此代码块始终至少运行一次
Integer count = 1;
do {
System.debug(count);
count++;
} while (count <= 10);
While 循环
while 循环在 Boolean 条件为 true 时重复执行代码块。与 do-while 不同,条件在第一次循环执行之前检查,因此代码块可能一次都不执行。
while (condition) {
code_block
}
花括号仅在代码块包含多条语句时必需。
Integer count = 1;
while (count <= 10) {
System.debug(count);
count++;
}
传统 For 循环
Apex 运行时引擎按以下五步顺序执行传统 for 循环:
- 执行初始化语句——可在一条语句中声明/初始化多个变量(逗号分隔),如
Integer i = 0, j = 0 - 执行退出条件检查。true 则继续,false 则退出
- 执行代码块
- 执行增量语句
- 返回步骤 2
for (init_stmt; exit_condition; increment_stmt) {
code_block
}
// 输出 1-10(j 演示多变量初始化)
for (Integer i = 0, j = 0; i < 10; i++) {
System.debug(i + 1);
}
列表/集合迭代 For 循环
遍历列表或集合中的每个元素。变量必须与列表/集合中元素的原始或 sObject 类型相同:
for (variable : list_or_set) {
code_block
}
Integer[] myInts = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (Integer i : myInts) {
System.debug(i);
}
SOQL For 循环有两种格式(变量必须与查询返回的 sObject 类型相同):
// 单变量格式
for (variable : [inline_soql_query]) { code_block }
// 列表变量格式
for (variable_list : [inline_soql_query]) { code_block }
迭代集合时的注意事项
迭代集合时不能直接修改该集合——这会导致错误。
- 添加元素:将新元素保存在临时列表/集合/映射中,迭代完成后再添加到原集合
- 删除元素(List):创建新列表并复制要保留的元素;或者将要删除的元素添加到临时列表,迭代完成后再移除。
List.remove执行线性搜索——频繁删除有时间成本,建议使用临时列表模式 - 删除元素(Map/Set):将要删除的键保存在临时列表中,迭代完成后再从集合中移除
本章涵盖了 Apex 中所有控制流机制——从简单的条件判断到 Switch 分支和多值匹配,再到五种循环类型和安全的集合迭代模式。掌握这些结构,你就能实现从简单验证到复杂多步骤业务流程的任何逻辑。