java 14 switch表达式必须有返回值、所有分支需覆盖或throw终止,须用->或yield,禁混用:和->;遇null未处理则抛nullpointerexception;支持多类型返回但需统一父类型或显式声明类型。

Java 14 Switch表达式怎么写才不报错
Java 14 的 switch 表达式不是 switch 语句的简单升级,它要求**必须有返回值**、**所有分支必须覆盖或用 throw 终止**,否则编译失败。常见错误是沿用老写法,在 case 后直接写语句块却不加 -> 或 yield。
- 老式语句用
:+break;新式表达式必须用->(箭头)分隔 case 和结果,或用yield显式返回 - 不能混用:
case A -> { ... }和case B: ... break;放在同一switch里会编译报错error: switch expression must be exhaustive - 如果类型推断失败(比如各分支返回不同类型),需显式声明目标变量类型,例如
String result = switch (x) { ... };
如何让Switch表达式返回不同类型的值
Java 14 的 switch 表达式支持多类型返回,但前提是所有分支返回值能统一为一个公共父类型(如 Object),或由上下文明确类型。编译器不会自动装箱/拆箱或做隐式转换。
- 返回基本类型时,所有分支必须一致:不能有的返回
int,有的返回Integer,否则触发incompatible types错误 - 想返回
Optional<string></string>?可以,但每个分支都得是Optional.of(...)或Optional.empty(),不能混入null - 使用
yield可以在复杂逻辑中延迟返回,但注意:yield必须在case的作用域内,不能出现在嵌套的if外层
示例:
String s = switch (day) {
case MON, TUE -> "weekday";
case SAT, SUN -> {
yield "weekend";
}
default -> throw new IllegalArgumentException("Unknown day: " + day);
};
为什么用了Switch表达式反而抛出NullPointerException
不是语法问题,而是 switch 表达式本身对 null 输入零容忍——它不会像旧 switch 那样静默跳过,而是直接抛 NullPointerException,除非你显式处理 null case。
- Java 14+ 的
switch表达式在运行时遇到null且没有case null:分支,就会立即抛出NullPointerException - 正确做法是加一个
case null ->分支(注意:不能写成case null:,那是语句写法) - 如果输入变量可能为
null,又不想每个地方都写case null,建议提前校验或用Objects.requireNonNull,别依赖switch做空值防御
Switch表达式在record和sealed class中的典型用法
Java 14 虽不支持 sealed class,但搭配 Java 15+ 的 sealed 或 Java 14 引入的 record,switch 表达式能发挥模式匹配前的最强枚举替代能力——尤其适合状态机、协议解析等场景。
立即学习“Java免费学习笔记(深入)”;
- 对
record字段做switch没特殊限制,但注意:不能直接switchrecord 实例本身(除非它重写了toString并靠字符串匹配,不推荐) - 配合
enum最安全:编译器能检查是否穷尽,default分支在 enum 上实际可省略(但加上更健壮) - 若未来升级到 Java 17+,记得把这里写的
switch表达式当作过渡方案——真正的模式匹配(case Point(int x, int y))会彻底改变写法
真正容易被忽略的是:Switch表达式在 lambda 或方法引用中无法直接使用,因为其作用域和类型推断会失效;需要先赋给局部变量再传递。








