在 Java 中,创建简单的数据载体(如 DTO、POJO)需要编写大量 样板代码:
示例(传统写法):
public class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Point{x=" + x + ", y=" + y + "}";
}
}
Java 16 的 记录类(Record) 通过一行代码实现相同功能:
public record Point(int x, int y) {}
自动生成的成员:
get
前缀)equals()
、hashCode()
和 toString()
values()
方法(返回所有字段值的数组)final
,无法修改(不可变性)。record User(String name, int age) {
// 自动生成 name() 和 age() 方法
}
User user = new User("Alice", 30);
System.out.println(user.name()); // 直接访问,无需 get 前缀
record Rectangle(double width, double height) {
// 紧凑构造器:校验参数
public Rectangle {
if (width <= 0 || height <= 0) {
throw new IllegalArgumentException("Dimensions must be positive");
}
}
// 自定义构造器:委托给规范构造器
public Rectangle(double side) {
this(side, side); // 正方形
}
}
记录类支持静态字段和方法,用于定义工具逻辑或常量:
record Circle(double radius) {
public static final double PI = Math.PI;
public double area() {
return PI * radius * radius;
}
}
记录类可直接在 instanceof
和 switch
中进行 模式解构:
public double calculateArea(Shape shape) {
return switch (shape) {
case Circle(double radius) -> Math.PI * radius * radius;
case Rectangle(double width, double height) -> width * height;
default -> throw new IllegalArgumentException("Unsupported shape");
};
}
记录类在编译后等价于一个 final 类,继承自 java.lang.Record
,包含:
equals()
、hashCode()
和 toString()
反编译示例:
public final class Point extends java.lang.Record {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int x() { return x; }
public int y() { return y; }
// equals, hashCode, toString 实现
}
record ApiResponse(boolean success, T data, String message) {}
// 使用示例
ApiResponse response = new ApiResponse<>(true, user, "Success");
record ComplexNumber(double real, double imaginary) {
public ComplexNumber add(ComplexNumber other) {
return new ComplexNumber(real + other.real, imaginary + other.imaginary);
}
}
record Pair(K key, V value) {}
// 返回多个值
public Pair getStats() {
return new Pair<>("Count", 100);
}
record UserStats(String name, long loginCount) {}
List stats = users.stream()
.map(user -> new UserStats(user.name(), user.loginCount()))
.toList();
特性 | 记录类 | Lombok @Data |
---|---|---|
不可变性 | 强制不可变 | 需手动声明 final |
代码生成方式 | 编译器原生支持 | 注解处理器 |
继承限制 | 无法继承其他类 | 可继承 |
反射可见性 | 所有方法明确可见 | 部分方法通过注解生成 |
未来演进 | 语言层面持续优化 | 依赖第三方库维护 |
记录类能否继承其他类?
java.lang.Record
。能否添加额外字段?
如何处理可选字段?
Optional
类型(需注意序列化兼容性)。记录类是否适合大型对象?
Java 16 的记录类通过 减少样板代码 和 增强数据透明性,彻底改变了 Java 处理简单数据类的方式。其核心优势包括:
未来演进方向:
通过合理运用记录类,开发者可显著提升代码质量和开发效率,尤其在 微服务数据模型、领域事件 和 数据处理管道 等场景中优势明显。