本文目录导读:

是的,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; // ❌ 编译错误,这不是解构声明
记录模式只能出现在 instanceof 或 switch 的上下文中。
版本要求
| 功能 | 预览版本 | 正式版本 |
|---|---|---|
| 记录类 | 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 或更高版本,记录模式在
switch和instanceof中都已正式可用。 - 如果你使用的是 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+,这已经是一个成熟且强大的特性,可以确保你的代码更简洁、类型更安全。