Java 14 原生支持 switch 表达式(JEP 361),无需插件;需正确配置 JDK 14、Maven 编译器版本及 IDE 语言级别;使用箭头语法(->)自动终止分支,无需 break;所有分支返回类型必须统一且穷尽,enum 可推断穷尽性,int/String 必须含 default。

Java 14 的 switch 表达式不是“插件”,不能通过插件启用
Java 14 原生支持 switch 表达式(JEP 361),不需要任何 IDE 插件或额外依赖。如果你在 IDE 中写不出 switch 表达式,大概率是项目没设对 Java 版本,或者用了旧版 JDK 编译。
关键判断点:javac -version 输出必须是 14 或更高;Maven 的 maven-compiler-plugin 需显式设 source 和 target 为 14;IntelliJ/Eclipse 也要检查 Project SDK 和 Language Level 是否同步为 14。
- IDEA:File → Project Structure → Project → Project SDK + Project language level → 均选 “14”
- Maven:
<source>14</source>和<target>14</target>必须同时存在,缺一不可 - 用
javac --release 14编译时会失败——--release不支持 14 的新语法,得用原生-source 14 -target 14
用 switch 表达式替代 if-else 赋值时,必须加 break 吗?
完全不用。Java 14 的表达式式 switch 采用“箭头语法”(->),每个分支自动终止,不穿透,也不需要 break。一旦用了 ->,传统 case L: ... break; 写法就报错。
错误示范:case 1: return "a"; break; → 编译失败,因为 break 在箭头分支中非法。
立即学习“Java免费学习笔记(深入)”;
正确写法示例:
String result = switch (day) {
case MON, TUE, WED -> "first half";
case THU, FRI -> "second half";
case SAT, SUN -> "weekend";
default -> throw new IllegalArgumentException("Unknown day: " + day);
};
- 多个常量可用逗号分隔(
MON, TUE, WED),不用重复写case - 每个分支必须有值(哪怕是
throw),否则编译报错:“switch expression does not cover all possible input values” - 如果漏了
default,且day是enum,编译器能推断是否穷尽;但如果是int或String,必须写default,否则过不了编译
为什么把 switch 当表达式用时,有时会报 “incompatible types”?
因为所有分支返回类型必须统一,且编译器不做隐式装箱/拆箱或宽化转换。常见陷阱是混用基本类型和包装类、或 null 与非空值。
反例:
Integer x = switch (n) {
case 1 -> 100; // int
case 2 -> 200L; // long → 编译失败!类型不兼容
case 3 -> null; // null 可以,但要求所有分支都是 Integer 或可转为 Integer 的引用类型
};
- 所有箭头右侧必须能统一为同一个编译期类型,比如全为
Integer、全为String,或全为void(仅限语句式switch,非表达式) - 想返回
int就全写int字面量;要Integer就全写Integer.valueOf(100)或用100(自动装箱成立,但前提是左侧声明为Integer且所有分支一致) -
default分支的类型也参与统一判断,不能单独“特殊处理”
从 Java 14 升到 15+ 后,switch 表达式行为有变化吗?
核心语法没变,但 Java 15 开始允许在 switch 表达式中使用 yield(JEP 378),用于从 case 块中提前返回值——这主要是为将来支持更复杂的分支逻辑铺路,目前绝大多数场景仍直接用 -> 更简洁。
注意:yield 只能在 -> 右侧是代码块(即大括号包裹)时才合法:
String s = switch (x) {
case 1 -> {
System.out.println("got 1");
yield "one"; // ✅ 正确
}
case 2 -> "two"; // ✅ 仍可用箭头+表达式
};
- 别误以为
yield替代了->:它只是补充,不是替代 - 如果用了
yield,该case分支就必须是块({...}),不能是单表达式 - Java 14 不认识
yield,用了直接编译失败,升级 JDK 后也得同步调高语言级别
真正容易被忽略的是:表达式式 switch 的“穷尽性检查”只在编译期做,运行时不会多一层校验;一旦你用 String 或 int 作 scrutinee,又没写 default,编译就过不去——这点和 enum 不同,得自己兜底。


















