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 小时前
分布式系统高可用性设计 - 监控与日志系统
后端
songroom2 小时前
【转】Rust: PhantomData,#may_dangle和Drop Check 真真假假
开发语言·后端·rust
红尘散仙2 小时前
Rust 终端 UI 开发新玩法:用 Ratatui Kit 轻松打造高颜值 CLI
前端·后端·rust
mldong2 小时前
mldong-goframe:基于 GoFrame + Vben5 的全栈快速开发框架正式开源!
vue.js·后端·go
canonical_entropy3 小时前
集成NopReport动态生成复杂Word表格
后端·低代码
come112343 小时前
Go 包管理工具详解:安装与使用指南
开发语言·后端·golang
绝无仅有3 小时前
OSS文件上传解析失败,错误:文件下载失败的排查与解决
后端·面试·架构
LaoZhangAI4 小时前
Kiro vs Cursor:2025年AI编程IDE深度对比
前端·后端
brzhang5 小时前
OpenAI 7周发布Codex,我们的数据库迁移为何要花一年?
前端·后端·架构