186. Java 模式匹配 - Java 21 新特性:Record Pattern(记录模式匹配)

186. Java 模式匹配 - Java 21 新特性:Record Pattern(记录模式匹配)

Java 在 SE 16 中引入了 record(记录类)作为简洁表示不可变数据的方式。而在 Java 21 ,记录又进化了一个层次------引入了 Record Pattern(记录模式匹配)!

这意味着我们可以直接在 if 或 switch 中解构 record 类型,提取其中的字段,写出更干净、更具表达力的代码。


✅ 回顾:什么是 Record?

java 复制代码
public record Point(int x, int y) {}

等价于一个包含:

  • 两个字段 x 和 y
  • 对应的访问器 x() 和 y()
  • 自动生成的构造函数和 equals()、hashCode()、toString() 方法

🎯 什么是记录模式(Record Pattern)?

记录模式允许你使用结构匹配语法,直接从 record 中解构并提取字段。

🌰 示例:基本模式匹配

java 复制代码
Object o = new Point(3, 4);

if (o instanceof Point(int x, int y)) {
    System.out.println("x = " + x + ", y = " + y);
}

✨ 说明:

  • o instanceof Point(int x, int y) 不只是判断 o 是 Point,还将其解构为 x 和 y
  • x 和 y 是自动绑定的局部变量

🧠 深入理解:记录模式的行为规则

✅ 1. 使用的是"规范构造函数"

  • record 可以声明多个构造函数
  • 但记录模式始终基于那个由编译器自动生成的"规范构造函数"
java 复制代码
record Point(int x, int y) {
    Point(int x) {
        this(x, 0);
    }
}

下面这段代码无法编译:

java 复制代码
Object o = ...;
// ❌ 不合法:没有 Point(int) 这种结构可匹配
if (o instanceof Point(int x)) {}

✅ 2. 你可以使用 var 做类型推断

java 复制代码
record Point(double x, double y) {}

Object o = new Point(1.1, 2.2);

if (o instanceof Point(var x, var y)) {
    System.out.println("类型被推断为 double: " + x + ", " + y);
}

✅ 3. 记录模式可以嵌套!

你可以在一个 record 中匹配另一个 record。

java 复制代码
record Point(double x, double y) {}
record Circle(Point center, double radius) {}

Object o = new Circle(new Point(1.0, 2.0), 5.0);

if (o instanceof Circle(Point(var x, var y), var radius)) {
    System.out.printf("圆心:(%f, %f), 半径:%f%n", x, y, radius);
}

💡 嵌套记录的结构匹配就像解包"洋葱层"。


✅ 4. 可与 switch 配合使用

java 复制代码
record Box(Object o) {}

Object o = new Box("hello");

String result = switch (o) {
    case Box(String s)  -> "字符串:" + s;
    case Box(Integer i) -> "整数:" + i;
    default             -> "其他类型";
};
System.out.println(result);

⚠️ 注意事项与坑点提醒

❌ 不支持装箱/拆箱转换

java 复制代码
record Point(Integer x, Integer y) {}

Object o = new Point(1, 2);

// ❌ 无法将 Integer 自动解构为 int
if (o instanceof Point(int x, int y)) {
}

你必须匹配 相同类型,不能依赖自动装箱/拆箱。


❌ 不支持不可能的类型匹配

java 复制代码
record Box(CharSequence o) {}

Object o = new Box("Java");

// ❌ Integer 不是 CharSequence 的子类,编译报错
switch (o) {
    case Box(String s)  -> System.out.println("字符串:" + s);
    case Box(Integer i) -> System.out.println("整数:" + i);
    default             -> System.out.println("其他类型");
}

⚠️ 所有模式类型必须是组件类型的 子类型或相同类型,否则编译错误。


🔥 补充实战场景

🎨 构建坐标系统中的图形识别

java 复制代码
record Point(int x, int y) {}
record Rectangle(Point topLeft, Point bottomRight) {}

Object shape = new Rectangle(new Point(0, 0), new Point(10, 10));

if (shape instanceof Rectangle(Point(int x1, int y1), Point(int x2, int y2))) {
    System.out.printf("矩形范围:(x1=%d, y1=%d) 到 (x2=%d, y2=%d)%n", x1, y1, x2, y2);
}

🧾 小结

功能 描述
✅ 记录模式 支持 record 的结构解构和字段绑定
📦 类型推断 支持 var 自动推断字段类型
🧱 支持嵌套 可用于深层嵌套的记录结构
💥 类型安全 匹配的类型必须是字段的子类型或相同类型
⚠️ 限制 不支持装箱/拆箱,不支持非规范构造函数结构匹配

🎓 建议练习:

  • 尝试用记录模式重写你的 DTO 判断逻辑
  • 编写带嵌套记录结构的 switch 分支逻辑
  • 结合 sealed class + record pattern 创建结构化的业务处理模型
相关推荐
裕晟资质规划1 分钟前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
念念清晰3 分钟前
000-OpenJDK17 源码构建:MacOS环境(M芯片)
java·后端
ShineWinsu9 分钟前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
月夏17 分钟前
Vue3 转 React:18 项对照表 + 5 个必踩的坑(附 7 天上手路线)
前端
广州华水科技25 分钟前
单北斗GNSS位移监测系统的应用与维护解析
前端
来福猿32 分钟前
SpringCloud Config 源码分析:配置拉取、刷新与多环境管理
后端·spring·spring cloud
普通人61 小时前
php+html+canvas实现树状打开的结构
开发语言·javascript·html5·1024程序员节
梦曦i1 小时前
uni-storage 0.1.0 发布:TTL过期管理+多实例隔离
前端·storage·uni-app x
猫头_2 小时前
AI 流式传输工程指南:模型吐出半截 JSON,前端如何边收边渲染?
前端·javascript·llm
console.log('npc')2 小时前
第 1 章 项目概述与环境搭建
前端·人工智能·大模型