1. switch 有哪些新变化
如果你在 Java 14 之前写过代码,switch 大致如下:
switch (day)
{
case MONDAY:
System.out.println("新的一周开始!");
break;
case FRIDAY:
System.out.println("周五,耶!");
break;
default:
System.out.println("平常的一天。");
break;
}
看起来没什么问题,但有这些麻烦:
- 必须记得写 break(否则会“落入”下一个 case)。
- 重复代码很多。
- 如果想返回值,就得事先声明一个变量,并在每个 case 内给它赋值。
Java 14+ 说:够了!该让 switch 更方便、更现代了。
主要改进:
- Switch 变成了表达式,不仅仅是语句——现在它可以返回值。
- 使用箭头 -> 的新语法,替代冒号和 break。
- 多个 case 可以用逗号合并——用于相同逻辑。
- 编译器会检查所有分支是否被处理(尤其是 enum)。
- 不再有“贯穿”(fall-through)的风险——只有显式才可能发生。
2. switch 表达式的语法
switch (znachenie)
{
case A, B -> rezultat1;
case C -> {
// 几个操作
yield rezultat2;
}
default -> rezultatPoUmolchaniyu;
}
-> 与
yield 的 switch 表达式语法
基本示例
直入主题:现在可以这样从 switch 返回值:
DayOfWeek day = DayOfWeek.MONDAY;
String message = switch (day)
{
case MONDAY, FRIDAY, SUNDAY -> "短周或休息日!";
case TUESDAY -> "星期二——艰难的一天。";
case WEDNESDAY, THURSDAY -> "周中!";
case SATURDAY -> "耶,星期六!";
// 如果不是所有分支都覆盖,必须有 default
default -> "有点奇怪的一天...";
};
System.out.println(message);
这里发生了什么:
- switch (day) 是一个会返回值的表达式。
- 箭头 -> 之后就是该 case 的结果。
- 多个 case 可以用逗号合并。
- 完全不需要 break——Java 自己知道分支在哪里结束。
- 可以直接把结果赋给变量 message。
数字示例
int code = 404;
String result = switch (code)
{
case 200 -> "OK";
case 400, 404 -> "客户端错误";
case 500 -> "服务器错误";
default -> "未知代码";
};
System.out.println(result);
字符串示例
String command = "start";
String status = switch (command)
{
case "start" -> "启动!";
case "stop" -> "停止!";
case "pause" -> "暂停...";
default -> "未知命令";
};
System.out.println(status);
配合 yield 的代码块
有时需要在一个 case 中执行多步操作(例如进行复杂计算或记录日志)。此时可以使用 { ... } 代码块并配合关键字 yield:
int n = 7;
String parity = switch (n % 2)
{
case 0 -> "偶数";
case 1 ->
{
System.out.println("检测到奇数: " + n);
yield "奇数";
}
default -> "有点奇怪";
};
System.out.println(parity);
重要:在代码块里必须写 yield,它为该 case 返回值。
3. 新语法的优势
无需写 break
在经典的 switch 中,忘记写 break 往往带来痛苦和神秘的 bug。在新语法里 break 完全不需要:每个分支都会自动结束。
编译器检查所有分支是否覆盖
如果你使用 enum 而没有处理所有值——没有 default 的情况下,编译器将不允许通过构建。这让代码更可靠。
没有“贯穿”(fall-through)
在经典的 switch 中,如果忘了 break,执行会“贯穿”到下一个 case。在新语法中这不可能(除非你使用语句块并显式写 break——但这里并不需要它)。
代码更简洁、更易读
自己对比一下:
之前:
String result;
switch (status) {
case "OK":
result = "一切都好";
break;
case "ERROR":
result = "错误";
break;
default:
result = "未知";
break;
}
之后:
String result = switch (status) {
case "OK" -> "一切都好";
case "ERROR" -> "错误";
default -> "未知";
};
多个 case——一套逻辑
case MONDAY, FRIDAY, SUNDAY -> "休息日或短的一天!";
4. 与经典 switch 的对比
| 特性 | 经典 switch | 新版 switch |
|---|---|---|
| 必须写 break | 是 | 否 |
| 贯穿(fall-through) | 是 | 否 |
| 可返回值 | 否(只能借助变量) | 是(表达式) |
| 多个 case 用逗号 | 否 | 是 |
| 检查所有分支 | 否 | 是(对 enum 尤其严格) |
| 简洁性 | 代码冗长 | 简洁明了 |
| 可用于 enum 与字符串 | 是 | 是 |
5. 与 enum 与字符串的兼容性
enum 示例
假设我们有一个枚举:
enum DayOfWeek
{
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
在新的 switch 中使用它:
DayOfWeek today = DayOfWeek.WEDNESDAY;
String mood = switch (today)
{
case MONDAY -> "起床真难...";
case FRIDAY -> "快到周末了!";
case SATURDAY, SUNDAY -> "耶,休息!";
default -> "工作日。";
};
System.out.println(mood);
配合 String 的示例
String season = "summer";
String activity = switch (season)
{
case "winter" -> "滑冰";
case "summer" -> "在湖里游泳";
case "autumn" -> "采蘑菇";
case "spring" -> "听鸟鸣";
default -> "未知的季节";
};
System.out.println(activity);
6. 将旧 switch 重写为新风格
旧写法:
int day = 3;
String dayName;
switch (day)
{
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
default:
dayName = "未知的日子";
break;
}
System.out.println(dayName);
新写法:
int day = 3;
String dayName = switch (day)
{
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
default -> "未知的日子";
};
System.out.println(dayName);
再举一例:多个 case——一套逻辑
int score = 5;
String grade = switch (score)
{
case 5, 6, 7 -> "良好";
case 8, 9, 10 -> "优秀";
default -> "需要加把劲";
};
System.out.println(grade);
7. 常见错误和注意事项
错误 1:未覆盖所有分支时缺少 default。 如果你对可能出现列举之外值的类型(例如 int 或 String)使用 switch 表达式,编译器会要求提供 default。对于 enum,如果没有处理所有值,default 也必须提供。
错误 2:在块中忘记写 yield。 如果在 case 中使用花括号(需要执行多步操作),别忘了 yield——没有它编译器会报错: "Missing yield statement"。
错误 3:返回类型不一致。 switch 表达式的所有分支必须返回相同类型的值;否则编译器不会放行代码。
错误 4:case 值重复。 同一个 case 不能写两次——编译器会直接提示错误。
GO TO FULL VERSION