Java 21 新特性之 记录模式(Record Patterns)

194 阅读4分钟

Java 21 引入了 记录模式(Record Patterns) ,这是对 Java 模式匹配功能的进一步增强。记录模式允许在 ​​switch​​ 表达式或语句中直接解构记录类的对象,从而简化代码并提高可读性。

这一特性是基于 Java 16 中引入的 Records(记录类) 和 Java 17 中引入的 模式匹配(Pattern Matching) 的扩展。它使得开发者可以更方便地处理复杂的数据结构,而无需手动访问记录类的字段。


什么是记录模式?

记录模式是一种新的模式匹配形式,允许在 ​​switch​​ 或其他模式匹配上下文中直接解构记录类的对象。通过记录模式,你可以将记录类的字段绑定到变量中,从而避免显式的字段访问和类型转换。


记录模式的基本用法

示例:

假设我们有一个简单的记录类:

record Point(int x, int y) {}

使用记录模式可以直接解构 ​​Point​​ 对象:

void printPointInfo(Object obj) {
    switch (obj) {
        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​​。
  • 不需要显式调用 ​​point.x()​​​ 或 ​​point.y()​​ 来访问字段。

支持嵌套记录模式

记录模式不仅支持简单的记录类,还支持嵌套的记录类。这使得它可以递归地解构复杂的数据结构。

示例:

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

record Rectangle(Point topLeft, Point bottomRight) {}

我们可以使用嵌套记录模式来解构 ​​Rectangle​​ 对象:

void printRectangleInfo(Object obj) {
    switch (obj) {
        case Rectangle(Point(int x1, int y1), Point(int x2, int y2)) ->
            System.out.println("Rectangle from (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ")");
        default ->
            System.out.println("Not a rectangle");
    }
}

解释:

  • ​Rectangle(Point(int x1, int y1), Point(int x2, int y2))​​​ 同时解构了 ​​Rectangle​​​ 和其内部的两个 ​​Point​​ 对象。
  • 这种嵌套模式非常适合处理复杂的层次化数据结构。

结合守卫条件(Guarded Patterns)

记录模式可以与守卫条件(​​when​​ 子句)结合使用,以进一步限制匹配的条件。

示例:

void checkDiagonalPoint(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");
    }
}

解释:

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

记录模式的优势

  1. 减少样板代码
  • 无需显式访问记录类的字段,直接解构对象即可。
  • 简化了复杂的嵌套数据结构的处理。
  1. 提高代码可读性
  • 记录模式使代码更加直观,逻辑清晰,减少了冗余的字段访问代码。
  1. 增强模式匹配能力
  • 结合类型测试模式、嵌套模式和守卫条件,能够处理更复杂的场景。
  1. 支持密封类(Sealed Classes)
  • 记录模式特别适合与密封类结合使用,因为编译器可以推断出所有可能的子类型,从而确保穷尽性检查。

记录模式的适用场景

  1. 处理记录类对象
  • 当你需要频繁访问记录类的字段时,记录模式可以显著减少样板代码。
  1. 嵌套数据结构
  • 如树形结构、图形结构等复杂数据模型,可以通过嵌套记录模式轻松解构。
  1. 多态对象处理
  • 在处理继承关系或接口实现时,可以结合记录模式和密封类,实现更优雅的模式匹配。
  1. 简化条件逻辑
  • 替代传统的 ​​if-else​​​ 或 ​​switch​​ 语句,尤其在需要类型检查和字段解构时。

示例:综合应用

以下是一个综合示例,展示了如何结合记录模式、嵌套模式和守卫条件来处理复杂的数据结构:

sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(Point topLeft, Point bottomRight) implements Shape {}
record Point(int x, int y) {}

double calculateArea(Shape shape) {
    return switch (shape) {
        case Circle(double radius) -> Math.PI * radius * radius;
        case Rectangle(Point(int x1, int y1), Point(int x2, int y2)) when x2 > x1 && y2 > y1 ->
            (x2 - x1) * (y2 - y1);
        default -> 0; // Invalid shape
    };
}

解释:

  • ​Circle(double radius)​​​ 解构了 ​​Circle​​ 对象,并计算面积。
  • ​Rectangle(Point(int x1, int y1), Point(int x2, int y2))​​​ 解构了 ​​Rectangle​​​ 和其内部的两个 ​​Point​​ 对象。
  • 守卫条件 ​​when x2 > x1 && y2 > y1​​ 确保矩形的坐标是有效的。

总结

记录模式是 Java 21 中一项重要的新特性,它极大地增强了模式匹配的能力,使开发者能够更高效地处理记录类和复杂的数据结构。通过减少样板代码、提高可读性和灵活性,记录模式为现代 Java 编程带来了更高的生产力。