4.1 if、else 与条件边界
前置知识:布尔表达式和短路逻辑
预计时间:25 分钟
完成标志:能写出互斥分支、处理边界值并避免悬空
else
if 只接受布尔条件
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:
int count = 1;
// if (count) { } // 编译错误条件先求值,只执行两个分支之一。若条件求值本身抛异常,两个分支都不会开始。
else if 从上到下选择第一个命中项
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 与互斥链不同
if (temperature < 0) {
System.out.println("freezing");
}
if (temperature < 10) {
System.out.println("cold");
}温度为 -5 时两条都会执行。若业务只允许一个标签,应使用互斥的 if / else if / else 链,或先定义清楚区间。
始终写花括号
Java 允许单条语句省略花括号:
if (ready)
start();但新增第二行时很容易制造视觉误导:
if (ready)
start();
recordMetric(); // 无论 ready 如何都会执行教程和团队代码统一写花括号:
if (ready) {
start();
recordMetric();
}这是降低维护风险的风格约束,不是“省略花括号的 Java 语法无效”。
else 归属最近的未配对 if
if (member)
if (spent >= 100)
discount();
else
explainThreshold();这里的 else 属于内层 if (spent >= 100)。缩进不会改变绑定。加花括号明确意图:
if (member) {
if (spent >= 100) {
discount();
} else {
explainThreshold();
}
}用提前返回降低嵌套
方法中连续的无效条件可以先退出:
static String route(boolean authenticated, int accessLevel) {
if (!authenticated) {
return "sign-in";
}
if (accessLevel < 5) {
return "request-access";
}
return "dashboard";
}提前返回不是固定规则。若方法需要统一清理或事务边界,应结合 try、资源管理和团队约定设计。
条件中的赋值可能合法
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 和条件赋值也就有了可检查的落点。
规范入口:JLS §14.9:if 语句。