Record Patterns 可直接解构多层嵌套 record,但要求所有中间类型均为 record、字段顺序与类型严格匹配,且 JDK ≥ 21 并启用预览特性。

Record Patterns 能直接解构多层嵌套的 record,省掉层层 instanceof + 强制转换 + getter 调用,但必须确保所有中间类型都是 record,且 JDK 版本 ≥ 21(需开启预览特性)。
record 必须全部定义为不可变数据载体
Record Patterns 只对 record 类型生效,普通 class、sealed 类或继承结构都不支持解构。嵌套时每一层都得是 record,比如 Person 包含 Address,Address 又包含 GeoLocation,三者都得用 record 声明。
record Person(String name, int age, Address address) {}record Address(String street, String city, GeoLocation location) {}record GeoLocation(double lat, double lng) {}
只要其中任意一层是普通 class(例如 class Address { ... }),整个嵌套模式就会编译失败,报错类似:illegal pattern: record pattern is not applicable to non-record type。
嵌套解构语法要严格匹配字段顺序与类型
嵌套写法不是“看起来像就行”,而是字段名、顺序、类型必须和 record 定义完全一致。比如 Point(int x, int y) 写成 Point(int y, int x) 或 Point(long x, long y) 都会编译不通过。
- 错误示例:
if (obj instanceof Person(String n, int a, Address(String s, String c, GeoLocation(double x, double y))))——GeoLocation字段名应为lat/lng,不是x/y - 正确写法:
if (obj instanceof Person(String name, int age, Address(String street, String city, GeoLocation(double lat, double lng))))
字段名可以重命名(如用 var n 替代 String name),但类型和顺序不能动;否则 JVM 在运行时无法完成自动解构绑定。
在 switch 中使用嵌套模式更安全,但需注意 null 和类型覆盖
switch 表达式比 instanceof 更适合嵌套场景,因为能自然处理多个分支,且编译器会强制检查穷尽性(配合 sealed 类时)。但要注意两点:
- 传入
null会导致NullPointerException,Record Patterns 不做空值防护,必须前置判空或用Objects.nonNull() - 如果
switch的表达式类型是Object,而某个case的嵌套模式过深,编译器可能提示“pattern is not compatible with switch selector type”,这时需要显式 cast 或改用instanceof分支先行过滤
典型安全写法:
switch (obj) {
case Person(String name, int age, Address(String street, String city, GeoLocation(double lat, double lng))) -> {
System.out.printf("%s lives at %s, %s (%.4f, %.4f)%n", name, street, city, lat, lng);
}
default -> System.out.println("Not a valid Person");
}
编译和运行必须启用预览特性
JDK 21 默认不启用 Record Patterns,即使代码写对了也会编译失败,报错:record patterns are a preview feature and are disabled by default。
- 编译时加参数:
javac --enable-preview --release 21 MyFile.java - 运行时加参数:
java --enable-preview MyFile - IDE(如 IntelliJ)需在项目设置中开启 “Use preview features” 并指定 Language Level 为 “21 (Preview)”
漏掉任一环节都会让嵌套解构完全失效——这不是语法问题,而是 JVM 层面未激活该特性。很多人卡在这一步,反复检查语法却忽略启动参数。
最易被忽略的是:嵌套深度本身没有硬性限制,但每增加一层,编译器校验负担就指数级上升;实际项目中超过 4 层嵌套时,建议拆分为多个独立 instanceof 判断,或引入 sealed 类配合守卫模式(Guarded Patterns)来提升可维护性。

















