Java switch
语句详解
一、基础语法演进
// 传统形式 (Java 1.0+)
switch (表达式) {
case 常量1:
语句;
break; // 防止穿透
case 常量2:
语句;
break;
default:
默认处理;
}
// 增强模式 (Java 12+)
switch (表达式) {
case 常量1 -> 语句; // 自动阻断穿透
case 常量2, 常量3 -> { // 多case合并
复合语句;
}
default -> 默认处理;
}
二、核心特性
-
表达式限制
- JDK 1-6:仅支持
int
/char
及包装类、枚举 - JDK 7+:支持
String
类型(区分大小写) - JDK 14+:支持模式匹配(预览特性)
- JDK 1-6:仅支持
-
类型匹配规则
Object obj = "test"; switch (obj) { case Integer i -> System.out.println("整数"); case String s -> System.out.println(s.length()); default -> System.out.println("未知类型"); }
-
返回值支持 (Java 14+)
使用yield
返回值的表达式形式:int code = switch (day) { case MONDAY -> 1; case TUESDAY -> { System.out.println("周二"); yield 2; } default -> 0; };
三、关键机制
-
穿透控制
- 传统
case
需显式break
,否则执行后续所有case - 箭头语法(
->
)自动阻断穿透,无需break
- 传统
-
作用域隔离
每个case
块形成独立作用域:switch (x) { case 1 -> { String msg = "one"; // 仅在此块有效 } case 2 -> { String msg = "two"; // 允许同名变量 } }
四、典型应用场景
场景 | 示例 |
---|---|
状态机处理 | 订单状态流转判断 |
命令解析 | CLI参数匹配执行 |
类型分发 | 处理多态替代方案 |
五、常见错误示例
错误类型 | 错误代码 | 修正方案 |
---|---|---|
缺失break | case 1: doA(); case 2: doB(); | 添加break或改用箭头语法 |
重复case值 | case 10: case 10: | 确保case常量唯一 |
类型不兼容 | switch(3.14) | 转换为支持的类型 |
六、最佳实践
-
防御性编程
switch (status) { case SUCCESS -> handleSuccess(); case FAILURE -> handleFailure(); default -> throw new IllegalStateException(); // 强制覆盖所有情况 }
-
模式匹配优化 (Java 17+)
switch (obj) { case null -> System.out.println("空值"); case String s when s.length()>5 -> System.out.println("长字符串"); case Integer i && i > 0 -> System.out.println("正整数"); }
-
性能优化
- 超过5个分支时,优先选择
switch
而非if-else
链 - 编译器对
switch
生成跳转表,时间复杂度O(1)
- 超过5个分支时,优先选择
七、代码风格建议
- 对齐
case
子句缩进 - 复杂逻辑封装为方法调用
- 多
case
合并时垂直排列:case JANUARY, MARCH, MAY, JULY, AUGUST -> days = 31;
扩展思考:对于大型状态机,可结合枚举类和
switch
实现,或采用状态模式提升可维护性。新版switch
表达式通过编译期类型检查,显著增强代码健壮性。