Java-record 记录类

结城 Java 13 次阅读 809 字 发布于 2026-05-04 预计阅读时间: 4 分钟


记录类的基本语法

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)
给时光以生命,给岁月以文明
最后更新于 2026-06-15