Java 14 新增的 `record` 关键字究竟有何奥秘?
摘要:1 概述: Java 关键字: record Java 的 record 关键字是在 Java 14 引入的预览特性,并在 Java 16 正式成为标准特性。 它提供了一种简洁的方式来声明不可变的数据载体类(Data Carrier Cla
1 概述: Java 关键字: record
Java 的 record 关键字是在 Java 14 引入的预览特性,并在 Java 16 正式成为标准特性。
它提供了一种简洁的方式来声明不可变的数据载体类(Data Carrier Classes)。
核心作用
1. 自动生成样板代码
当你声明一个 record 时,Java 编译器会自动生成:
自动生成
说明
private final 字段
所有组件字段都是 final 的
构造方法
包含所有字段的构造方法
getter 方法
按字段名命名(如 name() 而非 getName())
equals()
基于所有字段的比较
hashCode()
基于所有字段生成
toString()
包含类名和字段值的格式化字符串
2. 语法对比
传统类写法:
public final class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
// 还要手动写 equals, hashCode, toString...
}
record 写法:
public record Person(
String name
, int age
) {}
主要特性
不可变性(Immutable)
var person = new Person("Alice", 30);
// person.name = "Bob"; // ❌ 编译错误,字段是 final 的
紧凑构造方法(Compact Constructor)
可以在不重复参数列表的情况下添加验证逻辑:
public record Person(String name, int age) {
public Person {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
// 不需要写 this.name = name; 编译器自动处理
}
}
可以实现接口,但不能继承类
public record Employee(String name, double salary)
implements Comparable<Employee>, Serializable {
// 可以实现接口方法
}
可以添加额外方法
public record Rectangle(double width, double height) {
public double area() {
return width * height;
}
public static Rectangle square(double side) {
return new Rectangle(side, side);
}
}
使用场景
场景
示例
DTO(数据传输对象)
API 的请求/响应对象
数据库实体
简单的数据映射
配置类
读取的配置项
元组/多返回值
方法需要返回多个值
事件对象
领域事件
限制
不能继承其他类(隐式继承 java.lang.Record)
不能声明实例字段(只能有静态字段)
默认是 final 的,不能被继承
组件是 final 的,创建后不能修改
实际示例
// 定义
public record Point(int x, int y) {}
// 使用
var p1 = new Point(10, 20);
var p2 = new Point(10, 20);
System.out.println(p1.x()); // 10 (getter 直接是字段名)
System.out.println(p1.equals(p2)); // true
System.out.println(p1); // Point[x=10, y=20]
// 解构(Java 16+ 模式匹配预览,Java 21 正式)
if (p1 instanceof Point(int x, int y)) {
System.out.println("x=" + x + ", y=" + y);
}
总结
record 关键字的设计目的是减少样板代码,让开发者专注于数据本身的语义,而不是重复的 getter/setter/equals/hashCode/toString 等实现。它是 Java 向更简洁、更函数式编程风格演进的重要一步。
X 参考文献
