跳到内容

第 1 卷 / 第 4 章 / 第 1 课

4.1 if、else 与条件边界 ​

前置知识:布尔表达式和短路逻辑

预计时间:25 分钟

完成标志:能写出互斥分支、处理边界值并避免悬空 else

if 只接受布尔条件 ​

java
boolean authenticated = true;
int accessLevel = 6;

if (authenticated && accessLevel >= 5) {
    System.out.println("access granted");
} else {
    System.out.println("access denied");
}

Java 的 if 条件必须是 boolean 或可拆箱的 Boolean,不能用整数代替真假。Boolean 若为 null,拆箱时会抛 NullPointerException:

java
int count = 1;
// if (count) { } // 编译错误

条件先求值,只执行两个分支之一。若条件求值本身抛异常,两个分支都不会开始。

else if 从上到下选择第一个命中项 ​

java
int score = 82;
String grade;

if (score < 0 || score > 100) {
    grade = "invalid";
} else if (score >= 90) {
    grade = "excellent";
} else if (score >= 80) {
    grade = "good";
} else if (score >= 60) {
    grade = "pass";
} else {
    grade = "retry";
}

一旦某个条件为 true,后续分支不再求值。顺序属于业务逻辑:若先写 score >= 60,82 会过早进入 pass。

边界要成组测试:-1、0、59、60、79、80、89、90、100、101。只测 82 不能证明区间正确。

独立 if 与互斥链不同 ​

java
if (temperature < 0) {
    System.out.println("freezing");
}
if (temperature < 10) {
    System.out.println("cold");
}

温度为 -5 时两条都会执行。若业务只允许一个标签,应使用互斥的 if / else if / else 链,或先定义清楚区间。

始终写花括号 ​

Java 允许单条语句省略花括号:

java
if (ready)
    start();

但新增第二行时很容易制造视觉误导:

java
if (ready)
    start();
    recordMetric(); // 无论 ready 如何都会执行

教程和团队代码统一写花括号:

java
if (ready) {
    start();
    recordMetric();
}

这是降低维护风险的风格约束,不是“省略花括号的 Java 语法无效”。

else 归属最近的未配对 if ​

java
if (member)
    if (spent >= 100)
        discount();
    else
        explainThreshold();

这里的 else 属于内层 if (spent >= 100)。缩进不会改变绑定。加花括号明确意图:

java
if (member) {
    if (spent >= 100) {
        discount();
    } else {
        explainThreshold();
    }
}

用提前返回降低嵌套 ​

方法中连续的无效条件可以先退出:

java
static String route(boolean authenticated, int accessLevel) {
    if (!authenticated) {
        return "sign-in";
    }
    if (accessLevel < 5) {
        return "request-access";
    }
    return "dashboard";
}

提前返回不是固定规则。若方法需要统一清理或事务边界,应结合 try、资源管理和团队约定设计。

条件中的赋值可能合法 ​

java
boolean expected = false;
boolean actual = true;

if (expected = actual) {
    System.out.println("runs");
}

它能编译,是因为赋值表达式的类型为 boolean;这里赋入的值恰好为 true,所以分支也会执行。避免在条件中赋值,并启用 IDE 检查或静态分析。

专业速查 ​

需求做法
两路选择if / else
多个互斥区间按边界顺序写 else if
多个条件都可能执行多个独立 if
null 安全条件先判 null,再用 &&
降低嵌套小方法、提前返回、命名布尔表达式
证明边界正确测试每个分界点两侧和非法输入

离开这一页前 ​

拿成绩区间做一次口头检查:为什么 82 必须先经过 score >= 90 再到 score >= 80,独立的两个 if 又为何可能同时执行?再为 60、80、90 三个边界各列出相邻值。若这些问题能说清,悬空 else 和条件赋值也就有了可检查的落点。

→ 下一步:switch 语句与表达式

规范入口:JLS §14.9:if 语句。

Built with VitePress | Software Systems Atlas