控制流
条件判断、循环结构与跳转语句。
1. 条件分支 (Selection)
1.1 if-else 结构
1.1.1 基本用法
if (condition) {
// 条件为真时执行
}
// 另一个条件为真时执行
}
// 所有条件都为假时执行
}
1.1.2 嵌套 if-else
if (score >= 90) {
if (score >= 95) {
System.out.println("A+");
} else {
System.out.println("A");
}
}
System.out.println("B");
}
System.out.println("C");
}
1.1.3 卫语句 (Guard Clause)
对于复杂的条件判断,使用卫语句可以提高代码可读性:
public void processOrder(Order order) {
if (order == null) {
return;
}
if (!order.isValid()) {
System.out.println("Invalid order");
return;
}
if (order.getAmount() > MAX_AMOUNT) {
System.out.println("Amount too large");
return;
}
// 处理订单逻辑
}
1.2 switch 结构
1.2.1 传统 switch 语句
- 必须使用
break防止穿透 - 可以使用
default处理默认情况
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
case 4:
case 5:
System.out.println("Weekday");
break;
case 6:
case 7:
System.out.println("Weekend");
break;
default:
System.out.println("Invalid day");
}
1.2.2 Java 12+ switch 表达式
- 使用
->箭头语法,无需break - 可以直接返回值
- 支持
yield关键字返回复杂表达式
// 基本用法
String dayName = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3, 4, 5 -> "Weekday";
case 6, 7 -> "Weekend";
default -> "Invalid day";
}
// 使用 yield 返回复杂表达式
int result = switch (operation) {
case "add" -> {
yield a + b;
}
case "subtract" -> {
yield a - b;
}
default -> {
System.out.println("Invalid operation");
yield 0;
}
}
1.2.3 Java 17+ switch 模式匹配
// 模式匹配示例
Object obj = "Hello";
String result = switch (obj) {
case Integer i -> "Integer: " + i;
case String s -> "String: " + s;
case null -> "null";
default -> "Other";
}
2. 循环结构 (Iteration)
2.1 for 循环
2.1.1 标准 for 循环
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
2.1.2 增强型 for 循环 (for-each)
用于遍历数组、集合等可迭代对象:
// 遍历数组
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
// 遍历集合
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
2.1.3 带标签的 for 循环
outer: for (int i = 0; i < 3; i++) {
inner: for (int j = 0; j < 3; j++) {
if (j == 1) {
continue outer; // 跳过外层循环的当前迭代
}
System.out.println(i + ", " + j);
}
}
2.2 while 循环
- 先判断条件,后执行循环体
- 适用于循环次数不确定的场景
int i = 0;
while (i < 10) {
System.out.println(i);
i++;
}
2.3 do-while 循环
- 先执行循环体,后判断条件
- 保证循环体至少执行一次
int i = 0;
do {
System.out.println(i);
i++;
}
2.4 循环控制
2.4.1 break 语句
- 跳出当前循环
- 配合标签使用可以跳出多层循环
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // 跳出循环
}
System.out.println(i);
}
2.4.2 continue 语句
- 跳过当前迭代,进入下一次循环
- 配合标签使用可以跳过外层循环的当前迭代
for (int i = 0; i < 10; i++) {
if (i % 2 == 0) {
continue; // 跳过偶数
}
System.out.println(i);
}
3. 跳转语句 (Jumps)
3.1 return 语句
- 结束当前方法的执行
- 可以返回一个值(对于非 void 方法)
public int add(int a, int b) {
return a + b; // 返回计算结果
}
public void validate(int value) {
if (value < 0) {
return; // 提前结束方法
}
// 继续执行
}
3.2 标签 (Labels)
- 用于标识代码块
- 配合
break和continue使用可以控制多层循环
outerLoop: for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
System.out.println("Breaking outer loop");
break outerLoop;
}
System.out.println(i + ", " + j);
}
}
4. 实际应用案例
4.1 菜单选择
Scanner scanner = new Scanner(System.in);
System.out.println("1. Add");
System.out.println("2. Subtract");
System.out.println("3. Exit");
System.out.print("Enter your choice: ");
int choice = scanner.nextInt();
switch (choice) {
case 1 -> System.out.println("Add operation");
case 2 -> System.out.println("Subtract operation");
case 3 -> System.out.println("Exiting");
default -> System.out.println("Invalid choice");
}
4.2 查找元素
int[] numbers = {10, 20, 30, 40, 50};
int target = 30;
b boolean found = false;
for (int number : numbers) {
if (number == target) {
found = true;
break;
}
}
System.out.println(found ? "Found" : "Not found");
4.3 计算阶乘
public int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
5. 最佳实践 (Best Practices)
5.1 条件分支最佳实践
- 避免深层嵌套:
if-else嵌套不要超过 3 层 - 使用卫语句:对于简单的条件检查,使用卫语句提前返回
- 使用
switch替代多个if-else:当条件是离散值时,使用switch更清晰 - 使用枚举:对于固定的选项集合,使用枚举类型
5.2 循环最佳实践
- 选择合适的循环类型:
- 已知循环次数:使用
for循环 - 未知循环次数:使用
while循环 - 至少执行一次:使用
do-while循环 - 遍历集合:使用增强型
for循环
- 避免无限循环:确保循环条件最终会变为 false
- 注意循环变量:避免在循环体内修改循环变量
- 使用
break和continue提高效率:及时跳出或跳过不需要的迭代
5.3 性能考虑
- 循环不变量外提:将循环内不变的计算移到循环外
- 避免在循环中创建对象:尽量在循环外创建对象
- 使用
StringBuilder处理字符串拼接:在循环中拼接字符串时使用StringBuilder
6. 常见陷阱
switch语句的穿透效应:传统switch语句如果没有break会导致穿透- 浮点数比较:避免在条件中直接比较浮点数
- 空指针异常:在条件判断前检查对象是否为 null
- 死循环:确保循环条件最终会变为 false
更新日志 (Changelog)
- 2026-04-05: 细化控制流,引入 Java 12+ Switch 新特性。
- 2026-05-03: 扩展内容,添加实际应用案例、最佳实践和常见陷阱。