Java record 是从Java 14预览、Java 16正式推出的不可变数据载体类,自动提供构造器、访问器及equals/hashCode/toString,语法简洁如record Person(String name, int age) {},具备不可变性、透明数据模型和紧凑构造器支持。

Java record 是一种不可变的数据载体类,从 Java 14 作为预览特性引入,Java 16 起成为正式特性。它大幅简化了仅用于封装数据的类的定义,自动提供构造器、访问器(getter)、equals/hashCode/toString 等方法,且天然不可变、不可继承。
record 的基本语法
声明一个 record 只需一行简洁语法:
record Person(String name, int age) { }
这行代码等价于手动编写一个包含两个私有 final 字段、一个全参构造器、两个 public 访问器(name() 和 age())、重写的 equals、hashCode、toString 方法,以及隐式 final 类修饰的普通类。
立即学习“Java免费学习笔记(深入)”;
注意:字段名后不写类型修饰符(如 private final),也不写分号;括号内是“组件列表(components)”,决定 record 的逻辑结构和自动生成行为。
record 的核心特性
-
不可变性:所有组件字段默认为
private final,无法在构造后修改;record 类本身也是final,不能被继承 -
透明数据模型:record 的语义是“它是什么”,而非“它能做什么”;其状态完全由组件定义,
equals和hashCode基于组件值计算 -
自动生成标准方法:编译器生成规范的
public X(…)构造器、public T component()访问器、public boolean equals(Object)、public int hashCode()、public String toString() -
支持紧凑构造器(compact constructor):可用于校验或标准化组件值,无需重复赋值(如
record Point(int x, int y) { Point { if (x == 0 && y == 0) throw new IllegalArgumentException(); } })
record 的使用限制与注意事项
- 不能声明与组件同名的实例字段(会编译错误),但可声明静态字段或局部变量
- 不能重写组件访问器方法(如
name()),否则编译报错;但可以重写toString、equals等(不推荐,易破坏契约) - 不能继承其他类(隐式继承
java.lang.Record),也不能被继承(final) - 不支持传统类中的实例初始化块、非静态内部类等复杂结构;适合扁平、无行为的数据建模场景
何时该用 record?
适合用 record 的典型场景包括:
- DTO(数据传输对象)、VO(值对象)、API 响应封装类
- 函数式编程中的元组(如
record Pair<t u>(T first, U second) {}</t>) - 枚举的关联数据(如
enum Status { OK(200), ERROR(500); private final ResponseCode code; … }可替换为 record + 静态常量) - 替代匿名内部类或 lombok
@Data的轻量级方案(无需依赖、零运行时开销)
不适合的场景:需要可变状态、复杂业务逻辑、生命周期管理、代理/增强(如 Spring AOP)、或需实现多个接口并提供具体实现的方法。










