记录类的基本语法
record 是一种特殊的类,旨在以简洁的方式声明纯数据载体
如果不使用record进行声明,那么实体类只能这么写。
public final class Point {
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:基于字段值判断是否相等
@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;
}
// 重写 hashCode:确保在集合(如 HashMap)中表现一致
@Override
public int hashCode() {
return Objects.hash(x, y);
}
// 重写 toString:提供易读的字符串表示
@Override
public String toString() {
return "Point[x=" + x + ", y=" + y + "]";
}
}
如果使用record,那么书写的数据将会十分简洁
只需要下面这一行代码即可解决问题。
public record Point(int x, int y) {}
仅一行代码,等价于上面整个 Point 类!
自动生成的内容包括:
| 成员 | 说明 |
|---|---|
| 私有 final 字段 | private final int x; private final int y; |
| 公共构造器 | public Point(int x, int y) |
| 公共 getter 方法 | public int x() 和 public int y()(注意:不是 getX() ) |
| equals() / hashCode() | 基于所有组件(components)的值比较 |
| toString() | 格式如 Point[x=1, y=2] |
✅ 记录类是 final 的,不能被继承。
✅ 所有字段都是 private final,天然不可变。
记录类的使用示例
1. 基本使用
public record User(String name, int age, String email) {}
// 使用
User user = new User("Alice", 30, "alice@example.com");
System.out.println(user.name()); // Alice
System.out.println(user); // User[name=Alice, age=30, email=alice@example.com]
2. 自定义构造器(校验逻辑)
public record Product(String name, double price) {
// 紧凑构造器(Compact Constructor):自动赋值后执行
public Product {
if (price < 0) {
throw new IllegalArgumentException("价格不能为负");
}
// 注意:这里不需要 this.name = name; this.price = price;
}
}
3. 添加静态方法或实例方法
public record Circle(double radius) {
public double area() {
return Math.PI * radius * radius;
}
public static Circle unitCircle() {
return new Circle(1.0);
}
}
⚠️ 但不能添加实例字段(因为会破坏“纯数据”的语义)。
记录类的限制
| 不允许的操作 | 原因 |
|---|---|
| 继承其他类 | Record 已经继承了 java.lang.Record,Java 不支持多继承 |
| 声明实例字段 | 会破坏“状态仅由组件定义”的契约 |
| 提供 setter 方法 | 记录类是不可变的 |
| 显式 extends Record | 编译器自动处理,禁止手动写 |
记录类的显示示例如下
// 这里使用记录类语法,来自JDK16+,使用记录类可以很方便的将繁杂的普通类代码进行简化
// 例如这里的记录类,只需要记录name和age两个简单的字段,那么就直接记录类的参数里
// 如果需要重写记录类中的某些方法,只需要进行传统的重写方法模式,重写到记录内内部就行了
record Actor(String name, int age) {
@Override
public String toString() {
return "Actor{name='" + name + "', age=" + age + "}";
}
}
// 想添加一些具体的业务方法
record Actor(String name, int age) {
public boolean isAdult() {
return age >= 18;
}
@Override
public String toString() {
return "Actor{name='" + name + "', age=" + age + "}";
}
}
//如果不需要重写内部自动生成的方法,也不需要自定义方法,直接这样写
record Actor(String name, int age)
