应优先用switch判断编译期确定的常量值(如整数、字符、字符串、枚举),因其更清晰且可被JVM优化;范围判断、布尔表达式或运行时计算则必须用if-else。

Java里什么时候该用 if-else,什么时候该用 switch
判断依据不是“哪个更高级”,而是看匹配目标是否为**编译期确定的常量值**。如果判断的是变量是否等于几个固定整数、字符、字符串或枚举,switch 更清晰且可能被 JVM 优化成跳转表;如果涉及范围判断(如 score >= 90)、布尔表达式、或运行时计算结果,只能用 if-else。
常见误用:把 switch 套在 boolean 上——Java 不支持 switch (flag)(除非用 Boolean 枚举包装,但纯属绕弯)。
-
switch支持的类型:byte、short、int、char、String(JDK 7+)、enum(JDK 5+) -
if-else没有类型限制,可嵌套任意逻辑,比如if (obj != null && obj.isValid() && obj.getType() == Type.A) - JDK 14+ 的
switch表达式(带->和yield)适合需要返回值的场景,避免重复写return或赋值
避免 if-else 链漏掉 else 导致逻辑空转
当多个条件互斥且必须覆盖所有情况时(比如解析 HTTP 状态码),漏写 else 或末尾 else if 后没接 else,会导致某些输入不进任何分支,程序静默失败。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 先写最具体的条件(如
if (status == 404)),再写宽泛的(如else if (status >= 400)),避免逻辑被前置条件截断 - 末尾强制加
else { throw new IllegalArgumentException("Unknown status: " + status); },尤其在处理外部输入时 - IDE 通常能提示“Condition is always false”或“Unreachable code”,别忽略这些警告
switch 忘记 break 就会“穿透”执行
传统 switch 语句中,每个 case 块末尾必须显式写 break,否则会继续执行下一个 case 的代码——这不是 bug,是设计行为,但绝大多数业务场景下属于错误。
示例:
switch (day) {
case 1:
System.out.println("Monday");
case 2: // 没有 break!
System.out.println("Tuesday");
break;
default:
System.out.println("Other");
}
当 day == 1 时,会同时打印 Monday 和 Tuesday。
解决方式:
- 用 JDK 14+ 的新语法:
case 1 -> System.out.println("Monday");,自动终止,无需break - 老版本中,用 IDE 的 “Add ‘break’ statement” 快捷修复(IntelliJ / Eclipse 都支持)
- 若真需要穿透(极少见,如某些状态机),加注释说明:
// fall-through
字符串 switch 的坑:空指针和大小写敏感
switch 对 String 的判等本质是调用 String.equals(),所以传入 null 会直接抛 NullPointerException;而且默认区分大小写,"GET" 和 "get" 是两个不同分支。
安全写法:
- 先判空:
if (method == null) { ... } else switch (method) { ... } - 统一转大小写再比较:
switch (method.toUpperCase()) { case "GET": ... },但注意国际化场景(如土耳其语)可能出问题 - 更稳妥的方式:用
if ("GET".equalsIgnoreCase(method)),语义明确,无 NPE 风险
别为了用 switch 而硬套字符串,尤其是当分支数少于 3 个时,if-else 更直白、更易调试。










