switch 语句的模式匹配 - Sip of Java
Billy Korando 于 2023 年 11 月 13 日
经过几个预览阶段,switch
的模式匹配已在 JDK 21 中作为最终功能发布!在 switch
中添加模式匹配将为开发人员在使用 switch
时提供许多生活质量改进。让我们来看看吧!
模式匹配
模式匹配最初是在 Java 16 中添加的,用于 instanceof
的模式匹配。用于 instanceof
的模式匹配确实显著提高了代码可读性和可维护性,但在比较多个类型时仍然存在一些不足,例如以下示例
interface Shape{
double area();
}
record Circle(double diameter) implements Shape{...};
record Square(double side) implements Shape{...};
Shape shape = new Circle(10);
String message;
if(shape instanceof Circle c) {
message = "A circle with area of " + c.area();
} else if (shape instanceof Square s) {
message = "A square with area of " + s.area();
} else {
message = "Unknown shape";
}
在 Java 21 中,switch
已扩展为允许 case
标签也成为模式,从而简化了之前的示例,如下所示
interface Shape{
double area();
}
record Circle(double diameter) implements Shape{...};
record Square(double side) implements Shape{...};
Shape shape = new Circle(10);
String message = switch(shape){
case Circle c -> "A circle with area of " + c.area();
case Square s -> "A square with area of " + s.area();
default -> "Unknown shape";
};
保护条件
随着模式匹配的更新,switch
可以使用保护条件进一步细化 case
标签。这可以通过将检查条件保留在 case 标签内(而不是在 case
块内使用 if
语句)来帮助提高代码的可读性和可维护性;以下示例演示了如何使用保护条件
interface Shape{
double area();
}
record Circle(double diameter) implements Shape{...};
record Square(double side) implements Shape{...};
Shape shape = new Circle(10);
String message = switch(shape){
case Circle c when c.area() > 100
-> "A large circle with area of " + c.area();
case Circle c -> "A circle with area of " + c.area();
case Square s -> "A square with area of " + s.area();
default -> "Unknown shape";
};
处理 null
在对 switch
进行更新后,null
也作为 case 标签得到支持。这有助于提高可读性和可维护性,因为所有与 switch
相关的逻辑都可以在 switch
的主体中涵盖,而无需在之前进行 null
检查
interface Shape{
double area();
}
record Circle(double diameter) implements Shape{...};
record Square(double side) implements Shape{...};
Shape shape = new Circle(10);
String message = switch(shape){
case Circle c -> "A circle with area of " + c.area();
case Square s -> "A square with area of " + s.area();
case null -> "Null value";
default -> "Unknown shape";
};
穷举性
在 switch
中使用模式匹配时,即使像以下示例一样写成语句,switch
也必须是穷举的
interface Shape{
double area();
}
record Circle(double diameter) implements Shape{...};
record Square(double side) implements Shape{...};
Shape shape = new Circle(10);
switch(shape){
case Circle c -> System.out.println("A circle with area of " + c.area());
case Square s -> System.out.println("A square with area of " + s.area());
default -> System.out.println("Unknown shape");
};
密封层次结构
在 switch
中使用密封层次结构时,编译器可以读取层次结构以测试穷举性。在此示例中,default
case 是不必要的,因为所有路径都被 switch
涵盖。这可以帮助防止错误,因为如果将来向密封层次结构中添加新类,这将导致此代码出现编译器错误。
sealed interface Shape{
double area();
}
record Circle(double diameter) implements Shape{...};
record Square(double side) implements Shape{...};
Shape shape = new Circle(10);
String message = switch(shape){
case Circle c -> "A circle with area of " + c.area();
case Square s -> "A square with area of " + s.area();
//No default needed; compiler can read sealed hierarchy
};
记录模式
记录模式也成为 Java 21 中的最终功能,并在 switch
中得到支持
record Name(String fName, String lName, String mName) {};
Name host = new Name("William","Korando",37);
String printName = switch(host) {
case Name(var fName, var lName, var mName) -> lName + ", " + fName + " " + mName;
};
其他阅读材料
祝您编码愉快!