if-else 条件语句
本教程共 100 篇 · 第 19 篇 · 更新于 2026-08-05 · 约 6 分钟阅读
本节目标:掌握 if 的单分支、双分支、多分支三种写法,理解 else if 串联的判断顺序,避开边界、浮点比较、引用比较几个高频坑,能写出正确的条件判断代码。
程序最日常的需求就是”看情况办事”。Java 用 if 语句干这件事,它接收一个布尔值(true 或 false)当条件,条件成立就执行后面花括号里的代码。
单分支:if
最朴素的形式只关心”满足时做什么”:
public class Main {
public static void main(String[] args) {
int n = 70;
if (n >= 60) {
System.out.println("及格了");
}
System.out.println("END");
}
}
n >= 60 算出来是 true,所以打印”及格了”,接着照常打印 END。把 n 改成 50 再跑,条件变 false,花括号里整段被跳过,只看到 END。
Warning有人图省事,if 只有一条语句时不写花括号:
if (n >= 60) System.out.println("及格了"); System.out.println("恭喜你"); // 这行其实不在 if 里!缩进会骗人。第二行永远会执行,跟 if 无关。新手和 git 自动合并都容易在这栽跟头,所以一律写上花括号。
双分支:if-else
加上 else,条件不成立时走另一段:
int n = 50;
if (n >= 60) {
System.out.println("及格了");
} else {
System.out.println("挂科了");
}
else 不是必须的,但加上它能覆盖”否则”的情况,逻辑更完整。
多分支:else if 串联
选项超过两个时,用 else if 串起来:
int n = 85;
if (n >= 90) {
System.out.println("优秀");
} else if (n >= 60) {
System.out.println("及格");
} else {
System.out.println("挂科");
}
顺序决定结果,别写反
else if 是从上往下逐个判断的,一旦某个 if 命中,后面的分支整段跳过。所以判断范围要从大到小排:
// 错误写法:n=100 会先命中 n>=60,永远走不到"优秀"
if (n >= 60) { ... }
else if (n >= 90) { ... }
// 正确写法:大范围先判断
if (n >= 90) { ... }
else if (n >= 60) { ... }
else { ... }
Note也可以反过来从小到大判断,用
n < 60、n < 90这样的上界。关键是保证各区间不重叠、不遗漏。
边界条件:> 和 >= 不一样
看一段常见的错:
int n = 90;
if (n > 90) {
System.out.println("优秀");
} else if (n >= 60) {
System.out.println("及格");
}
本想 90 分算优秀,结果 > 把 90 挡在门外,打印出”及格”。> 和 >= 差一个等号,含义天差地别,写判断时把边界值(比如正好 60、正好 90)在脑子里过一遍。
浮点数别用 == 比相等
计算机存小数有误差,1 - 9.0/10 算出来并不是精确的 0.1。直接用 == 比较多半失败:
double x = 1 - 9.0 / 10;
if (Math.abs(x - 0.1) < 0.00001) { // 看差值的绝对值够不够小
System.out.println("x 约等于 0.1");
}
正确做法是比较”两者差的绝对值是否小于一个极小阈值”。
引用类型用 equals,不是 ==
比较两个字符串内容是否相同,要用 equals():
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
if (s1.equals(s2)) {
System.out.println("内容相同");
}
== 对引用类型比较的是”是不是同一个对象”,不是”内容是否一样”。s1 == s2 这里会是 false,因为它们是两个不同的对象。
Warning如果
s1是null,s1.equals("hello")会直接抛NullPointerException。稳妥写法是把不为 null 的字面量放前面:"hello".equals(s1),这样 s1 为 null 时也只会返回 false,不会崩。
嵌套 if
if 里面还能再套 if,处理”大条件里再分小条件”:
int age = 20;
boolean hasTicket = true;
if (age >= 18) {
if (hasTicket) {
System.out.println("可以入场");
} else {
System.out.println("请先买票");
}
} else {
System.out.println("未成年禁止入场");
}
嵌套能表达更细的逻辑,但层次别太深,三层以上就该想想是不是该拆成方法了。
悬垂 else:else 到底跟着谁
不写花括号时,嵌套 if 会出现一个经典歧义:
int age = 15;
boolean vip = false;
if (age >= 18)
if (vip)
System.out.println("VIP 入场");
else
System.out.println("未成年禁止入场"); // 缩进在骗人
看缩进像是 else 配外层的 if (age >= 18),实际编译器的规则是「else 永远跟最近的、还没配对的 if」——它配的是里层的 if (vip)。所以 age = 15 时这段什么都不打印。
修法只有一个:每个 if / else 都写花括号。花括号一加,谁跟谁配一目了然,编译器和你的理解就不会分家。
条件里的 && 和 || 会短路
else if 链是从上往下一个个试,命中就停。单个条件内部的 &&、|| 也有类似的「能不算就不算」行为,叫短路求值:
A && B:A为false时,B根本不执行,整体直接是false。A || B:A为true时,B根本不执行,整体直接是true。
这不只是性能优化,更是防崩的常用手法:
String name = null;
if (name != null && name.length() > 3) { // 顺序不能反
System.out.println("名字够长");
}
name != null 是 false,后半段 name.length() 被短路掉,不会抛 NullPointerException。两个条件调换位置,程序立刻崩。
Warning单个
&和|也能连布尔值,但它们不短路,两边都会算。上面的例子改成name != null & name.length() > 3,照样抛空指针。日常判断一律用&&和||。
动手练一练
写一个 checkGrade 的小逻辑:输入分数,90 以上打印”优秀”,60 到 89 打印”及格”,否则打印”不及格”。重点练 else if 的边界:想清楚 89 和 90 分别落哪边,再补一个”负数直接提示非法”的分支。
Tip把边界值(0、59、60、89、90、100)逐个测一遍,是检验 if 边界是否写对的笨办法,也是最有效的办法。
易错提醒
最常见的两个坑:一是把 if (score = 60) 写成赋值(单等号),本意是比较却变成了赋值;二是多个 else if 顺序排反,比如先判断 >= 60 再判断 >= 90,导致 95 分也被前面的分支截走。范围判断要想清楚互斥关系。
第一个坑值得单独说说。C 语言里 if (score = 60) 能编译通过,赋值结果 60 被当成”真”,是著名的隐蔽 bug 来源。Java 把这条路堵死了——score = 60 的结果是 int,不是 boolean:
error: incompatible types: int cannot be converted to boolean
if (score = 60) {
^
1 error
但有个例外要当心:两边都是 boolean 时,编译器拦不住。
boolean ok = false;
if (ok = true) { // 这是赋值!ok 被改成 true,条件恒成立
System.out.println("永远会进来");
}
这段能编译、能运行,还顺手把 ok 改掉了。判断布尔变量直接写 if (ok) 就行,别画蛇添足加 == true,也就不会手滑写成 =。
小结
if 是条件判断的主力,else 覆盖否则情况,else if 串起多分支;顺序和边界是新手最容易翻车的地方;浮点别用 ==,引用比较用 equals 并防 null。把这几条记牢,判断逻辑基本就稳了。
拓展:组合条件与字符串比较
真实判断往往是”多条件叠加”。比如”成绩及格且出勤率达标”才算通过,用 &&(并且)连接;“是会员或者消费满额”享受折扣,用 ||(或者)连接。注意 Java 里逻辑运算符是 && 和 ||,不是单 &/|(后者是位运算,行为不同且可能不短路)。
还有个高频坑:判断字符串内容相等,必须用 equals,不能写 ==。== 比的是”是不是同一个对象”,equals 比的是”内容一不一样”。例如 input.equals("exit") 才是正确写法。Java 的布尔类型只有 true/false,没有”非零即真”那一套,所以 if (score) 这种写法在 Java 里直接编译报错。
常见疑问
Q:if 里能定义变量吗?
能,但它只在那对花括号里活着,出去就没了:
if (score >= 60) {
String msg = "及格";
System.out.println(msg);
}
// System.out.println(msg); // 编译错误:msg 已出作用域
要在 if 外面用,就把声明提到 if 之前。
Q:条件很长很复杂,怎么写才不乱?
抽成有名字的布尔变量,让代码自己解释自己:
boolean adult = age >= 18;
boolean paid = balance >= price;
boolean inStock = stock > 0;
if (adult && paid && inStock) {
System.out.println("下单成功");
}
比一行塞五个条件好读得多,调试时还能单独打印每个变量看是哪一项没满足。
Q:三元运算符能替代 if-else 吗?
只在「二选一取个值」时能替代,比如 int max = a > b ? a : b;。分支里要执行多条语句,还是老实用 if-else。三元运算符也别嵌套,套两层就没人看得懂了。