`record` 和传统的 `POJO` 类有什么区别?
时间: 2025-07-11 12:06:18 浏览: 10
### 3.1 不可变性与字段定义
Java 中的 `record` 是一种用于定义不可变数据类的语言级特性,编译器会自动生成构造方法、访问器方法、`equals()`、`hashCode()` 和 `toString()` 方法。相比之下,传统 POJO(Plain Old Java Object)类需要手动编写这些方法,通常包含较多样板代码,例如字段声明、构造函数、getter 和 setter 方法等[^2]。
```java
// 传统 POJO 类
public class Person {
private final int id;
private final String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() { return id; }
public String getName() { return name; }
// equals(), hashCode(), toString() 需要手动实现...
}
// Record 等效实现
public record Person(int id, String name) {}
```
### 3.2 继承与扩展能力
`record` 类型隐式为 `final`,不能继承其他类,但可以实现接口。而传统 POJO 类支持继承和多态,具有更强的扩展性。例如,以下代码展示了 `record` 实现 `Serializable` 接口的情况:
```java
public record Point(int x, int y) implements Serializable {}
```
由于 `record` 的设计初衷是简化不可变数据载体的创建,因此它不适合用于复杂的业务逻辑或需要继承已有类结构的场景[^4]。
### 3.3 构造逻辑与验证支持
虽然 `record` 默认使用简洁的语法生成构造方法,但它也支持紧凑构造函数(Compact Constructor),允许插入自定义逻辑(如参数校验),而无需显式声明所有字段并赋值。这使得开发者可以在保持简洁的同时进行必要的验证处理。例如:
```java
public record StudentQueryDto(String name, String sex, Integer[] age, int page, int size) {
public StudentQueryDto {
if (age == null || age.length == 0) {
throw new IllegalArgumentException("Age array cannot be null or empty");
}
}
}
```
在传统 POJO 类中,构造逻辑和字段赋值需要手动完成,灵活性更高但也更繁琐。
### 3.4 编译器生成内容与内部机制
`record` 本质上是一种语法糖,编译后会生成一个继承自 `java.lang.Record` 的 `final` 类,并自动包含私有字段、构造方法、getter 方法以及常用的对象方法。例如:
```java
public final class Point extends java.lang.Record {
private final int x;
private final int y;
// 自动生成构造方法、getters、toString、equals、hashCode ...
}
```
这种机制减少了开发者的工作量,提高了代码可读性和维护性,适用于配置类、DTO(数据传输对象)等简单数据结构封装场景[^4]。
### 3.5 使用限制与适用范围
`record` 的字段默认为 `final`,不支持可变状态;不能继承其他类;也不适合封装复杂业务逻辑。此外,`record` 需要 JDK 14 或更高版本,如果项目需兼容低版本 JDK,则无法使用该特性。相比之下,传统 POJO 类没有上述限制,适用于更广泛的应用场景[^4]。
阅读全文
相关推荐



















