Record解构是Java 21+对record类型的原生模式匹配支持,允许在instanceof和switch中直接拆出final字段,无需getter调用,要求类型严格为record且组件名完全一致,不支持继承或可变字段。

Record解构就是直接拆出字段,不是调getter
Java里“对象解构”不是语法糖,而是模式匹配对record类的原生支持——它让你跳过point.x()这种访问器调用,直接在instanceof或switch里把字段名当局部变量用。
- 必须是
record类型(普通class、Lombok生成的类、甚至sealed子类但非record都不行) - 解构变量名和record组件名完全一致,大小写敏感,不支持重命名(比如不能写
Point(int a, int b)来映射x/y) - 嵌套record也能解构:
Circle(Point center, double radius)可写成Circle(Point(int cx, int cy), double r),但注意括号层级和逗号位置 - 编译器不生成新字段,只是语法层面绑定;解构出的变量是
final,不可赋值
在instanceof里解构,别再写两次强制转换
老写法:if (obj instanceof Point) { Point p = (Point) obj; System.out.println(p.x() + p.y()); }——既啰嗦又容易漏掉null检查或类型不匹配。
- 新模式直接写:
if (obj instanceof Point(int x, int y)) { System.out.println(x + y); } -
obj为null时整个条件为false,不会NPE,安全 - 如果
obj不是Point,括号内变量x/y根本不可见,作用域严格受限 - Java 21+才支持完整解构;Java 16–20只支持
instanceof Type var这种简单绑定,不支持括号解构
switch表达式中用Record Pattern,编译器帮你兜底
处理密封类+record组合时,switch配合解构是最清晰的写法,而且Java 21起编译器会检查是否穷尽所有子类型。
- 示例:
Shape s = new Circle(new Point(1, 2), 3.0);,搭配sealed interface Shape permits Circle, Rectangle - 写法:
return switch (s) { case Circle(Point(int x, int y), double r) -> "circle at (" + x + "," + y + "), r=" + r; case Rectangle(Point(int x1, int y1), Point(int x2, int y2)) -> "rect from " + x1 + "," + y1; default -> throw new IllegalStateException("unknown shape"); }; - 如果漏掉某个
permits子类,Java 21+编译报错:pattern matching does not cover all possible subtypes -
default分支在密封类下其实可以省略(前提是所有子类都已列出),但建议保留以防未来扩展破坏兼容性
别把Record Pattern当万能解包器——它不支持继承和可变字段
Record Pattern只认“规范结构”:组件列表完全匹配、字段全final、无自定义构造逻辑。一旦破戒,解构就失效。
立即学习“Java免费学习笔记(深入)”;
- 加了自定义
canonical constructor但没显式委托?解构仍可用;但加了compact constructor且修改了参数值?解构可能绕过校验,行为不可靠 - record里声明
private final String name;再加个public String getName() { return name.toUpperCase(); }?解构出来的还是原始name值,和getter返回值无关 - 试图对
public record Person(String name, int age) implements Serializable做解构?没问题;但换成class Person extends SomeBase?直接编译失败,Pattern不认继承链 - Java 25虽支持record里写
static方法和default方法,但这些不影响解构——解构只看组件声明本身
最容易被忽略的是:Record Pattern的解构能力完全依赖编译期静态分析,运行时没有反射式“取字段”逻辑。这意味着IDE提示、编译错误、甚至泛型擦除后的类型信息,都会影响能否写出合法解构式。写之前先确认JDK版本和record定义是否“够干净”。








