Java记录类(Record)深度解析:不可变数据建模的最佳实践
一、记录类核心特性
Java 14引入的记录类(Record)是声明不可变数据模型的简洁方式:
// 传统Java类
public final class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getters, equals, hashCode, toString等
}
// Record等效实现
public record Person(String name, int age) { }
自动获得:构造函数、getter、equals()、hashCode()、toString()
二、高级用法与自定义
1. 自定义构造函数
public record User(String username, String email) {
// 紧凑构造函数(参数校验)
public User {
Objects.requireNonNull(username);
if (email == null || !email.contains("@")) {
throw new IllegalArgumentException("无效邮箱");
}
}
// 添加业务方法
public String domain() {
return email.substring(email.indexOf('@') + 1);
}
}
2. 实现接口
public record Timestamp(long value)
implements Comparable<Timestamp> {
@Override
public int compareTo(Timestamp other) {
return Long.compare(this.value, other.value);
}
}
三、模式匹配结合使用
Java 16+的模式匹配与Record完美配合:
// 定义几何图形Record
sealed interface Shape
permits Circle, Rectangle, Triangle {
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}
}
// 模式匹配处理
double area(Shape shape) {
return switch (shape) {
case Circle(var r) -> Math.PI * r * r;
case Rectangle(var w, var h) -> w * h;
case Triangle(var b, var h) -> 0.5 * b * h;
};
}
四、实际应用场景
1. DTO数据传输对象
// API响应结构
public record ApiResponse<T>(
boolean success,
String message,
T data
) { }
// 使用示例
ApiResponse<User> response = new ApiResponse(
true,
"操作成功",
new User("张三", "zhangsan@example.com")
);
2. 领域建模
// 电商领域模型
public record Product(
String id,
String name,
BigDecimal price,
List<Category> categories
) { }
public record Category(String id, String name) { }
五、性能分析与最佳实践
对比项 | 传统类 | Record类 |
---|---|---|
代码量 | ~30行 | 1行 |
内存占用 | 标准对象头 | 优化后的对象头 |
序列化性能 | 依赖实现 | 内置优化 |
最佳实践:
- 适合纯数据载体场景
- 优先用于DTO/VO等传输对象
- 避免定义可变状态
- 结合sealed class使用更安全
六、与Lombok对比
1. Lombok @Data
@Data
@AllArgsConstructor
public class Person {
private String name;
private int age;
}
2. Record优势
- 语言原生支持,无第三方依赖
- 明确的不可变性语义
- 更好的模式匹配支持
- JVM级别优化