Java 21 新特性之 模式匹配的switch表达式和语句增强

Java 21 对 模式匹配的​switch​表达式和语句 进行了进一步增强,这是在 Java 17 和 Java 19 中引入的初步模式匹配功能的基础上的重大改进。这一特性旨在使 ​​switch​​ 更加灵活、强大,并支持更复杂的类型检查和数据解构操作。

以下是 Java 21 中模式匹配的 ​​switch​​ 表达式和语句增强的关键点:


1. 增强的模式匹配能力

Java 21 的 ​​switch​​ 表达式和语句支持更丰富的模式匹配形式,包括:

  • 类型测试模式(Type Test Pattern) :用于检查对象是否属于某种类型。
  • 记录模式(Record Pattern) :用于解构记录类的对象。
  • 嵌套模式(Nested Patterns) :支持在同一个 ​case​ 中使用多个模式。

示例:

假设我们有以下类层次结构和记录类:

java 复制代码
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}

我们可以使用增强的 ​​switch​​ 来处理这些类型:

scss 复制代码
double area = switch (shape) {
    case Circle c -> Math.PI * c.radius() * c.radius();
    case Rectangle r -> r.width() * r.height();
};
System.out.println("Area: " + area);

2. 支持记录模式(Record Patterns)

记录模式允许在 ​​switch​​ 中直接解构记录类的对象,从而避免显式的字段访问。

示例:

csharp 复制代码
record Point(int x, int y) {}

void printPointInfo(Object obj) {
    switch (obj) {
        case Point(int x, int y) when x == y -> System.out.println("Diagonal point at (" + x + ", " + y + ")");
        case Point(int x, int y) -> System.out.println("Point at (" + x + ", " + y + ")");
        default -> System.out.println("Not a point");
    }
}

解释:

  • ​case Point(int x, int y)​ 中,​Point​ 类型的对象被自动解构成 ​x​​y​
  • 可以结合守卫条件(​when​ 子句)进行额外的逻辑判断。

3. 支持嵌套模式(Nested Patterns)

嵌套模式允许在一个 ​​case​​ 中组合多个模式,从而实现更复杂的匹配逻辑。

示例:

假设我们有一个嵌套的记录类:

scss 复制代码
record Box(Shape shape) {}

我们可以使用嵌套模式来解构 ​​Box​​​ 和其内部的 ​​Shape​​:

csharp 复制代码
double calculateArea(Box box) {
    return switch (box) {
        case Box(Circle c) -> Math.PI * c.radius() * c.radius();
        case Box(Rectangle r) -> r.width() * r.height();
    };
}

解释:

  • ​case Box(Circle c)​ 匹配一个包含 ​Circle​​Box​,并将其解构成 ​c​
  • 这种嵌套模式可以递归地解构复杂的数据结构。

4. 守卫条件(Guarded Patterns)

守卫条件允许在 ​​case​​ 中添加额外的布尔表达式,以进一步限制匹配的条件。

示例:

csharp 复制代码
void checkNumber(Object obj) {
    switch (obj) {
        case Integer i when i > 0 -> System.out.println("Positive integer: " + i);
        case Integer i -> System.out.println("Non-positive integer: " + i);
        default -> System.out.println("Not an integer");
    }
}

解释:

  • ​when i > 0​ 是一个守卫条件,只有当 ​i > 0​ 为真时,才会匹配该分支。

5. 默认行为与穷尽性检查

在 ​​switch​​ 表达式中,所有可能的情况都必须被覆盖,否则会导致编译错误。这种设计确保了代码的健壮性。

示例:

java 复制代码
sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}

double area = switch (shape) {
    case Circle c -> Math.PI * c.radius() * c.radius();
    case Rectangle r -> r.width() * r.height();
    // 缺少 default 会报错,因为 Shape 是密封类
};

注意:

  • 如果 ​Shape​ 是密封类(Sealed Class),编译器可以推断出所有可能的子类型,因此 ​default​ 分支可以省略。
  • 如果 ​Shape​ 不是密封类,则需要显式地添加 ​default​ 分支。

6. 箭头语法与传统语法的混合使用

Java 21 允许在同一个 ​​switch​​​ 中混合使用箭头语法(​​->​​​)和传统语法(​​:​​)。这提供了更大的灵活性。

示例:

csharp 复制代码
void printDay(String day) {
    switch (day) {
        case "MONDAY" -> System.out.println("Start of the work week");
        case "FRIDAY": 
            System.out.println("End of the work week");
            break;
        default:
            System.out.println("Midweek days");
            break;
    }
}

解释:

  • 使用箭头语法的分支不需要 ​break​
  • 使用传统语法的分支仍需要手动添加 ​break​

7. 总结与优势

  1. 更简洁的代码
  • 使用模式匹配和箭头语法,减少了冗余的类型转换和 ​break​ 语句。
  • 直接解构对象,避免了显式的字段访问。
  1. 更强大的表达能力
  • 支持记录模式、嵌套模式和守卫条件,能够处理复杂的类型和数据结构。
  1. 提高安全性
  • 编译器的穷尽性检查确保了所有可能的情况都被覆盖,减少了遗漏分支的风险。
  1. 更好的可读性
  • 通过清晰的模式匹配逻辑,使代码更加直观,易于理解和维护。

适用场景

  • 复杂的数据结构:如嵌套的记录类或密封类。
  • 多态对象处理:如处理继承关系或接口实现。
  • 简化条件逻辑 :替代传统的 ​if-else​​switch​ 语句,尤其在需要类型检查和解构时。

通过这些增强,Java 21 的 ​​switch​​ 表达式和语句变得更加现代化,能够更好地适应现代开发需求,同时提高了代码的简洁性和安全性。

相关推荐
间彧1 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧1 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧1 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧1 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧1 小时前
Spring Cloud Gateway详解与应用实战
后端
EnCi Zheng2 小时前
SpringBoot 配置文件完全指南-从入门到精通
java·spring boot·后端
烙印6013 小时前
Spring容器的心脏:深度解析refresh()方法(上)
java·后端·spring
Lisonseekpan3 小时前
Guava Cache 高性能本地缓存库详解与使用案例
java·spring boot·后端·缓存·guava
4 小时前
JUC专题 - 并发编程带来的安全性挑战之同步锁
后端
凯哥19704 小时前
迁移PostgreSQL数据库教程
后端