Java模式匹配能解构记录吗

wen java案例 1

本文目录导读:

Java模式匹配能解构记录吗

  1. 核心语法
  2. 关键细节与规则
  3. 版本要求
  4. 实际示例:处理泛型记录

是的,Java 的模式匹配可以解构记录(Record),这是 Java 16 中正式引入记录类后,在 Java 17 及更高版本中通过 switch 模式匹配和 instanceof 模式匹配支持的特性。

核心语法

在模式匹配中,记录的模式看起来就像调用它的构造器,但实际上是解构(将记录分解为其组件)。

使用 instanceof 解构

public record Point(int x, int y) {}
void printPoint(Object obj) {
    if (obj instanceof Point(int x, int y)) {  // 这里解构出 x 和 y
        System.out.println("x=" + x + ", y=" + y);
        // 可以直接使用 x 和 y 变量,无需调用 point.x()
    }
}

使用 switch 表达式/语句解构

这是更强大的用法,特别是结合 sealed 类或复杂的继承结构时。

sealed interface Shape permits Circle, Rectangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
double area(Shape shape) {
    return switch (shape) {
        case Circle(double r) -> Math.PI * r * r;
        case Rectangle(double w, double h) -> w * h;
    };
}
// 也可以多层嵌套解构
public record Location(String name, Point coordinates) {}
String describe(Object obj) {
    return switch (obj) {
        case Location(String name, Point(int x, int y)) 
            when x > 0 && y > 0 -> name + " is in the first quadrant";
        case Location(String name, Point(var x, var y)) 
            -> name + " is somewhere else";
        default -> "Unknown";
    };
}

关键细节与规则

嵌套解构

你可以像上面 Location 的例子一样,在模式内部嵌套另一个记录模式,深度没有硬性限制,但建议保持可读性。

使用 var 进行类型推断

如果你不关心或不想写出组件类型,可以使用 var

if (obj instanceof Point(var x, var y)) { // x, y 的类型会自动推断为 int
    ...
}

守卫条件 (when 子句)

可以在模式匹配后添加额外的布尔条件:

switch (shape) {
    case Rectangle(double w, double h) when w == h -> System.out.println("这是一个正方形");
    case Rectangle(double w, double h) -> System.out.println("普通矩形");
    ...
}

记录模式不能单独在声明中使用

你不能这样写:

Point(int x, int y) = somePoint; // ❌ 编译错误,这不是解构声明

记录模式只能出现在 instanceofswitch 的上下文中。

版本要求

功能 预览版本 正式版本
记录类 Java 14 (Preview) Java 16
instanceof 模式匹配 (基础) Java 14 (Preview) Java 16
记录模式 (instanceof) Java 19 (Preview) Java 21
记录模式 (switch) Java 17, 18, 19, 20... Java 21

实际结论:

  • 如果你使用的是 Java 21 或更高版本,记录模式在 switchinstanceof 中都已正式可用
  • 如果你使用的是 Java 17-20,记录模式在 instanceof 中可用(Java 19+ 稳定),但在 switch 中可能仍处于预览阶段(需要 --enable-preview)。

实际示例:处理泛型记录

record Pair<T, U>(T first, U second) {}
void process(Object obj) {
    if (obj instanceof Pair(String s, Integer i)) {
        System.out.println("字符串: " + s + ", 数字: " + i);
    }
    // 使用 var 忽略泛型
    if (obj instanceof Pair(var first, var second)) {
        System.out.println("任意类型的对");
    }
}
特性 支持情况
解构记录 ✅ 完全支持
嵌套解构 ✅ 支持
泛型记录解构 ✅ 支持(可以指定具体类型或使用 var
守卫条件 ✅ 支持
用于 instanceof ✅ 支持(Java 19+ 稳定,Java 21 最终确定)
用于 switch ✅ 支持(Java 21+ 稳定)
单独声明解构 (解构) 不支持(Java 没有“解构声明”的语法)

如果你在使用 Java 21+,这已经是一个成熟且强大的特性,可以确保你的代码更简洁、类型更安全。

抱歉,评论功能暂时关闭!