← [ BACK_TO_NOTES ]

Java 流程控制

Java 的条件、循环与分支:if/switch、for/while、break/continue 如何组织结构化控制流。

#concept #growing #dev #java

[!info] related notes

Java 流程控制

这个概念为什么出现

业务规则是分支与循环的组合:库存够不够、状态机如何跳转、批处理如何扫单。Java 提供结构化控制流,避免回到随意 goto 风格。

[!abstract] 一句话理解 用 if/else、switch、for/while/do-while 与 break/continue 组织分支与迭代;if/循环条件须为 boolean 或可拆箱的 Boolean;没有 C 式整数真值转换。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:批处理任务按订单状态分流并跳过已取消单

扫描订单数组:取消跳过,待支付计数,已支付累加金额。
教学点:for-each、if、continue、switch。

public class OrderBatch {
    enum Status { CREATED, PAID, CANCELLED }

    static final class Order {
        final String id;
        final Status status;
        final int amountCents;

        Order(String id, Status status, int amountCents) {
            this.id = id;
            this.status = status;
            this.amountCents = amountCents;
        }
    }

    // summarize:生成批处理摘要。
    //
    // 业务意图:一遍扫描得到待支付数量与已支付总额。
    // 教学点:continue 跳过取消单;switch 按状态分流。
    static void summarize(Order[] orders) {
        int pending = 0;
        long paidSum = 0; // 避免多个 int 金额累加时发生 int 溢出
        for (Order o : orders) {
            if (o.status == Status.CANCELLED) {
                // 取消单不进入后续统计。
                continue;
            }
            switch (o.status) {
                case CREATED -> pending++;
                case PAID -> paidSum += o.amountCents;
                default -> throw new IllegalStateException("unhandled status: " + o.status);
            }
        }
        System.out.println("pending=" + pending + " paidSum=" + paidSum);
    }

    public static void main(String[] args) {
        Order[] orders = {
            new Order("1", Status.CREATED, 100),
            new Order("2", Status.PAID, 200),
            new Order("3", Status.CANCELLED, 300),
            new Order("4", Status.PAID, 50)
        };
        summarize(orders);
    }
}

建议运行:

javac OrderBatch.java && java OrderBatch

期望输出:

pending=1 paidSum=250

结合场景再看三个关注点

  1. 条件须为 boolean 或可拆箱的 Boolean:if (stock) 对 int 不成立,Boolean 为 null 时会拆箱失败。
  2. 本例的 default 显式失败,不会静默忽略新状态;空 default 没有防漏作用。完整枚举 switch 表达式也可不写 default,让重新编译时检查穷尽性。
  3. continue/break 降低嵌套,但过深循环应拆方法。

核心概念与准确模型

1. if / else

  • 条件类型可为 boolean 或 Boolean;后者会拆箱,null 会抛 NPE。
  • else if 按顺序选择第一个成立分支;先保证业务优先级正确,只有重排不改变语义时才考虑成本。

2. switch

  • switch 表达式与箭头标签在 Java 14 正式提供;箭头也可用于 switch 语句,不能只凭 -> 判断它是表达式。Java 21 正式支持模式 switch。
  • 对枚举与字符串切换很实用
  • 注意 break 贯穿(传统冒号语法)问题;箭头形态避免贯穿

3. 循环

形态适合
for已知次数/索引扫描
增强 for遍历数组/Iterable
while条件驱动
do-while至少一次

4. break / continue / 标签

  • break 结束循环或 switch
  • continue 进入下一次迭代步骤:普通 for 先执行更新表达式,while/do-while 则检查相应循环条件。
  • 标签 break 可跳出多层——可读性成本高,优先重构

边界情况与反直觉行为

  1. 增强 for 没有统一的“禁止修改”规则:可修改数组元素或可变对象;集合结构修改是否允许及如何检测取决于其迭代契约,见集合篇。
  2. 浮点当循环条件易死循环或误差。
  3. 空数组 for-each 安全,零次迭代。

常见误区

[!warning] 常见误区:switch 忘记 break 传统冒号语法会贯穿到下一 case。箭头标签 -> 更不易踩坑。

工程实践

  1. 复杂分支用多态或策略表替代巨型 switch(OOP 阶段再深化)。
  2. 循环体内避免重复计算不变式。
  3. 批处理记录“处理/跳过/失败”计数,便于对账。

本节总结

  • 结构化分支与循环是业务规则骨架
  • boolean 条件、枚举 switch、增强 for 是日常主力
  • 版本带来的 switch 表达式应查当前 JDK 文档

自测题

  1. 为什么 if (1) 在 Java 非法?
  2. 批处理中 continue 与把条件嵌套在大 if 里如何取舍?
参考答案
  1. 条件只能是 boolean 或可拆箱的 Boolean,整数 1 不会隐式转为布尔值。
  2. 早继续可降低嵌套、突出主路径;但过多 continue 也要拆方法保持清晰。

延伸阅读与资料来源

资料类型支撑内容
JLS Statements规范语句与控制流
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本