浅浅了解 Java 中的 switch
Coding 时正好遇到了一个
switch
的高版本特性,以前没见过,就正好兴致来了去简单了解下switch
随着 Java 版本更新的变化。
Java 1.0 至 Java 4: 传统 switch
语句的基础支持
支持类型: 仅限整型 (byte
、short
、int
) 和字符型 (char
)
switch (expression) {
case value1:
// 代码块
break;
case value2:
// 代码块
break;
default:
// 默认代码块
}
特性限制:
- 必须显式使用
break
防止贯穿 (fall-through) case
值需为编译时常量,且不可重复- 无法处理字符串或复杂对象
Java 5
新增支持: 允许 case
标签使用枚举常量
意义: 增强类型安全性, 避免魔法值
enum Day { MONDAY, TUESDAY, WEDNESDAY }
Day day = Day.TUESDAY;
switch(day) {
case MONDAY:
System.out.println("Monday");
break;
case TUESDAY:
System.out.println("Tuesday");
break;
default:
System.out.println("Other day");
}
Java 7
新增支持:支持字符串类型和包装类(Byte, Short, Character, Integer)
String fruit = "apple";
switch(fruit) {
case "apple":
System.out.println("Apple is red.");
break;
case "banana":
System.out.println("Banana is yellow.");
break;
default:
System.out.println("Unknown fruit.");
}
实现原理:
-
通过调用
hashCode()
将字符串转换为整型, 再通过equals()
验证匹配, 确保唯一性 -
反编译示例:
switch(fruit.hashCode()) { case 99162322: if (fruit.equals("apple")) { /* case代码 */ } break; // ... }
注意事项:
- 区分大小写,依赖
equals()
的精确匹配 - 性能略低于整型
switch
, 但可读性显著提升
Java 12
语法革新:
- 箭头语法 (
->
) : 替代break
, 避免贯穿问题 - 多值匹配: 允许逗号分隔多个
case
值 - 表达式化:
switch
可作为表达式返回值 - 通过
break
关键字返回值
通过 break
关键字返回值例子
return switch (day) {
case "Monday":
break "Weekday";
case "Tuesday":
break "Weekday";
case "Wednesday":
break "Weekday";
case "Thursday":
break "Weekday";
case "Friday":
break "Weekday";
case "Saturday":
break "Weekend";
case "Sunday":
break "Weekend";
default:
break "Unknown";
};
通过箭头运算符返回值
return switch (day) {
case "Monday" -> "Week day";
case "Tuesday" -> "Week day";
case "Wednesday" -> "Week day";
case "Thursday" -> "Week day";
case "Friday" -> "Week day";
case "Saturday" -> "Weekend";
case "Sunday" -> "Weekend";
default -> "Unknown";
};
case
中多个值的例子
return switch (day) {
case "Monday","Tuesday","Wednesday","Thursday","Friday" -> "Week day";
case "Saturday", "Sunday" -> "Weekend";
default -> "Unknown";
};
Java 13
新增关键字: yield
用于从 switch
块中返回值,替代 break
结合表达式的方式
String type = switch (obj) {
case Integer i:
yield "整数";
case String s:
yield "字符串";
default:
yield "未知类型";
};
Java 14
标准化特性: 将 Java 12-13 的预览特性(通过标记参数 -enable-preview=true
开启)定为标准功能
Java 17 (Preview)
模式匹配: 可以在 switch
条件下传递对象,并且可以在 switch case
标签中检查该对象的不同类型, 如下面的例子:
return switch (obj) {
case Integer i -> "It is an integer";
case String s -> "It is a string";
case Employee s -> "It is a Employee";
default -> "It is none of the known data types";
};
保护模式
before:
case Employee emp:
if(emp.getDept().equals("IT")) {
yield "This is IT Employee";
}
after:
return switch (obj) {
case Integer i -> "It is an integer";
case String s -> "It is a string";
case Employee employee when employee.getDept().equals("IT") -> "IT Employee";
default -> "It is none of the known data types";
};
空值处理
对于 null
的处理
static void test(Object obj) {
switch (obj) {
case null -> System.out.println("null!");
case String s -> System.out.println("String");
default -> System.out.println("Something else");
}
}
在此预览功能之前,当 obj
为 null
时, 此示例会抛出 NullPointerException
而在此后则是正常处理能够打印出 null!
也可以组合起来用:
static void testStringOrNull(Object obj) {
switch (obj) {
case null, String s -> System.out.println("String: " + s);
default -> System.out.println("Something else");
}
}
不过值得一提的是如果选择器表达式的计算结果为 null
并且 switch
块没有 null
case 标签, 那么就会正常抛出 NullPointerException
String s = null;
switch (s) {
case Object obj -> System.out.println("This doesn't match null");
// No null label; NullPointerException is thrown
// if s is null
}
评论区