jdk 12+ switch 表达式必须显式返回值,所有分支需覆盖(含default),用yield而非break;字符串switch性能较差且区分大小写;jdk 17+模式匹配需启用预览功能。

switch 表达式返回值必须显式处理
JDK 12+ 的 switch 支持表达式写法(带 -> 箭头),但它不再是语句,而是表达式——这意味着它必须有明确的返回值,且所有分支都要覆盖,不能漏掉 default 或遗漏枚举常量。
常见错误现象:Incompatible types: bad type in switch expression 或编译失败提示 “missing return statement”。
- 如果
switch用在赋值或方法返回处,每个分支末尾不能用break,得用表达式(如字面量、方法调用)或{ ... yield value; }块 - 枚举类型做
switch时,即使你“确定”只会有几个值,JDK 仍要求显式列出全部或加default;否则编译报错 - 使用
yield时,它只能出现在-> { ... }块内,不能单独和箭头同行(case A -> yield "x"是非法的)
String result = switch (day) {
case MON, TUE, WED -> "weekday";
case THU -> { yield "almost weekend"; }
case FRI -> "yes";
default -> "unknown";
};
字符串 switch 在 JDK 7+ 支持,但性能不如枚举或 int
虽然 switch 支持 String 从 JDK 7 就开始,但底层是编译器生成的哈希查找 + equals 回退逻辑,不是跳转表。实际性能比 int 或枚举慢,尤其分支多时。
- 不要在高频循环里对长字符串做
switch,考虑预转换成枚举或Map查表 -
null输入会直接抛NullPointerException,不进任何case;需要提前判空 - 字符串比较是区分大小写的,
"A"和"a"是不同分支,不会自动归一化
yield 和 break 在 switch 表达式中不能混用
这是最容易混淆的点:老式 switch 语句用 break 防止穿透,新式表达式用 yield 返回值。两者语法层级不同,强行混用会导致编译错误。
立即学习“Java免费学习笔记(深入)”;
-
case X -> break;是非法的——箭头右边必须是表达式或带yield的块 -
case X: yield "a"; break;也是错的——yield已经结束该分支,后面语句不可达 - 想执行多行逻辑再返回?必须用
{ ... yield value; },且yield是唯一出口
int code = switch (status) {
case "OK" -> 200;
case "NOT_FOUND" -> {
log.warn("404 hit");
yield 404;
}
default -> -1;
};
模式匹配(JDK 17+)让 switch 能解构对象,但需开启预览
如果你用的是 JDK 17 或更新版本,并启用了预览功能,switch 可以直接匹配类型并解构,比如 case Point(int x, int y)。但这不是默认开启的。
- 编译要加
--enable-preview --source 17(或对应版本),运行也要加--enable-preview - 模式匹配分支必须穷尽,比如
case null和case String s之间若漏了其他引用类型,可能编译失败 - 目前不支持在同一个
switch中混用传统 case 和模式 case(如case 1:和case String s:),会报错
真要用,先确认 JDK 版本、预览开关、以及目标类型是否支持模式(比如 record、sealed class 更友好)。










