很多人吐槽Java代码又臭又长,一个对象要写大量的setter,getter,而用Lombok会被说还要依赖第三方,所以从JDK14开始有了record数据类型

虽然 Java 没有叫“结构体”(struct)的关键字(像 C/C++ 那样),但从 Java 14 开始,Java 引入了 record 作为一种轻量级的数据载体类,它的作用和 C/C++ 中的“结构体”非常相似 —— 主要用于封装数据


✅ 一句话定义

record 是 Java 14+ 引入的一种 不可变的数据类(data class),用于简洁地定义只包含数据的类,自动提供构造器、equals()hashCode()toString() 等方法。


📌 为什么需要 record

record 出现之前,我们经常要写这样的“POJO”类(Plain Old Java Object):

public class Point {
    private final double x;
    private final double y;

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

    public double getX() { return x; }
    public double getY() { return y; }

    // 自动生成的:equals(), hashCode(), toString()
    @Override
    public boolean equals(Object o) { ... }
    @Override
    public int hashCode() { ... }
    @Override
    public String toString() { return "Point[x=" + x + ", y=" + y + "]"; }
}

代码冗长,但功能很简单:只是存两个数据字段 xy

有了 record,这一切可以简化为一行:

public record Point(double x, double y) {}

✅ 编译器会自动生成:

  • 私有 final 字段 x 和 y
  • 公共的访问器方法 x() 和 y()(不是 getX()
  • 构造器 Point(double x, double y)
  • equals()hashCode()toString() 方法

✅ 基本语法

public record 类名(字段类型 字段名, 字段类型 字段名, ...) {
    // 可选:自定义方法、静态字段、静态方法、构造器等
}

示例:表示一个用户

public record User(String name, int age, String email) {}

// 使用
User user = new User("张三", 25, "zhangsan@example.com");
System.out.println(user); // User[name=张三, age=25, email=zhangsan@example.com]
System.out.println(user.name()); // 获取 name 字段(注意不是 getName())

✅ record 的特点(重点)

特性 说明
🔒 不可变(Immutable) 所有字段自动是 private final,不能修改
🧱 只能包含 final 字段 构造后数据不能变,适合做数据传输对象
📦 自动实现 equals / hashCode / toString 基于字段值比较,适合用在 SetMap 中
🚫 不能继承其他类 因为 record 隐式继承 java.lang.Record
✅ 可以实现接口 public record Point(...) implements Serializable { }
⚙️ 可以添加静态字段或方法 用于工具方法
🛠️ 可以自定义构造器 用于参数校验或规范化

✅ 自定义构造器示例

public record Person(String name, int age) {
    // 自定义构造器:校验年龄
    public Person {
        if (age < 0) {
            throw new IllegalArgumentException("年龄不能为负数");
        }
        // 注意:不需要写赋值语句,编译器自动完成
    }

    // 可以添加额外方法
    public boolean isAdult() {
        return age >= 18;
    }
}

使用:

Person p = new Person("李四", 20);
System.out.println(p.isAdult()); // true

✅ record vs class 什么时候用?

场景 推荐使用
只想封装数据,不可变 ✅ record
需要可变状态(setter) ❌ 用普通 class
需要继承某个类 ❌ 用 class
作为 DTO、POJO、API 参数/返回值 ✅ record
与 JSON 序列化配合(如 Spring Boot) ✅ 完美支持(Jackson 2.13+)

✅ 实际应用场景

  1. Spring Boot 中作为 API 请求/响应对象
public record LoginRequest(String username, String password) {}
public record LoginResponse(String token, long expires) {}
  1. 函数返回多个值
public record Result(int code, String message, Object data) {}
  1. 数据传输对象(DTO)
public record UserDTO(String name, String email, List<String> roles) {}

✅ 注意事项

  • record 是 Java 14+ 的特性(预览),Java 16+ 正式支持
  • 如果你用的是 Java 8,无法使用 record
  • 字段访问器是 name() 而不是 getName()(这是 record 的规范)

✅ 总结

项目 说明
是什么 Java 14+ 引入的轻量级数据类
用途 替代“只有字段 + getter + toString”的 POJO 类
特点 不可变、自动方法、简洁、安全
类比 类似 C/C++ 的 struct,但更安全、功能更强
推荐使用场景 DTO、配置类、函数返回值、数据封装

🎯 一句话总结

record 是 Java 给“纯数据类”设计的语法糖,让你用 一行代码 实现过去要写 20 行的 POJO 类,更简洁、更安全、更现代

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐