​Java 中的 record 类详解

时间:2025-03-29 14:35:10

AI生成

Java 中的 record 类详解

record 是 Java 14 引入的预览特性,并在 Java 16 正式成为标准功能。它是一种特殊的类,主要用于简化不可变数据载体(Data Carrier)的建模,例如 DTO(数据传输对象)、实体类、配置类等。


1. record 的核心特点

**(1) 自动生成样板代码**

record 会自动生成以下内容:

  • 私有 final 字段(对应构造参数)。
  • 公共构造方法(参数与声明顺序一致)。
  • Getter 方法(方法名与字段名相同,无 get 前缀)。
  • **equals()hashCode()toString()** 方法。

**(2) 不可变性(Immutable)**

  • 所有字段默认是 final 的,无法修改。
  • 适合表示纯数据,如坐标点、用户信息等。

**(3) 简洁语法**

相比传统类,record 的声明更简洁:

// 传统类
public class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // 手动编写 getter、equals、hashCode、toString...
}

// 使用 record
public record Point(int x, int y) {}

2. record 的基本用法

**(1) 定义 record**

public record User(String name, int age) {}
  • 这里 User 是一个 record,包含 name 和 age 两个字段。

**(2) 创建对象**

User user = new User("Alice", 30);
  • 使用自动生成的构造方法初始化。

**(3) 访问字段**

System.out.println(user.name()); // 输出 "Alice"(注意是 name() 不是 getName())
System.out.println(user.age());  // 输出 30

**(4) 自动生成的 toString()**

System.out.println(user); // 输出: User[name=Alice, age=30]

**(5) 比较对象**

User user1 = new User("Alice", 30);
User user2 = new User("Alice", 30);
System.out.println(user1.equals(user2)); // true(自动比较字段值)

3. record 的限制

  1. 字段不可变
    不能直接修改字段值(除非通过反射破坏封装)。
  2. 不能继承其他类
    record 隐式继承 java.lang.Record,不能再继承其他类。
  3. 不能声明非静态字段
    所有字段必须在 record 头部声明。
  4. 不能添加实例字段
    只能在构造参数中定义字段。

4. 自定义 record 行为

虽然 record 自动生成方法,但可以显式重写它们:

**(1) 自定义构造方法**

public record User(String name, int age) {
    // 紧凑构造方法(可做参数校验)
    public User {
        if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
    }
}

**(2) 重写 toString()**

public record User(String name, int age) {
    @Override
    public String toString() {
        return name + " (" + age + " years old)";
    }
}

**(3) 添加静态方法**

public record Point(int x, int y) {
    // 静态工厂方法
    public static Point origin() {
        return new Point(0, 0);
    }
}

5. record vs. 传统类 vs. Lombok

特性

**record**

传统类

Lombok @Data

代码简洁性

⭐️ 极简(一行定义)

❌ 需手动编写样板代码

⭐️ 注解驱动

不可变性

⭐️ 默认不可变

❌ 需手动设为 final

⚠️ 依赖注解配置

继承

❌ 不能继承其他类

✅ 可以

✅ 可以

字段扩展性

❌ 只能在头部声明字段

✅ 可任意添加字段

✅ 可任意添加字段

适用场景

DTO、值对象、配置类

复杂业务逻辑

需要减少样板代码的传统类


6. 适用场景

  1. DTO(数据传输对象)
public record ApiResponse<T>(boolean success, T data) {}
  1. 不可变值对象
public record Coordinate(double latitude, double longitude) {}
  1. 配置类
public record DatabaseConfig(String url, String username, String password) {}

7. 总结

  • **record 是 Java 中表示纯数据的轻量级类**,自动生成构造方法、Getter、equals/hashCode/toString
  • 适合不可变数据建模,如 DTO、配置、坐标等。
  • 不能替代传统类,复杂逻辑仍需使用完整类或 Lombok。

示例:

public record Product(String id, String name, double price) {}

// 使用
Product product = new Product("p123", "Laptop", 999.99);
System.out.println(product.name()); // "Laptop"

record 让 Java 在处理数据时更接近 Kotlin 的 data class,是现代化 Java 开发的重要特性!