Java14新特性:record(类似于结构体)
·
很多人吐槽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 + "]"; }
}
代码冗长,但功能很简单:只是存两个数据字段 x 和 y。
有了 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 |
基于字段值比较,适合用在 Set、Map 中 |
| 🚫 不能继承其他类 | 因为 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+) |
✅ 实际应用场景
- Spring Boot 中作为 API 请求/响应对象
public record LoginRequest(String username, String password) {}
public record LoginResponse(String token, long expires) {}
- 函数返回多个值
public record Result(int code, String message, Object data) {}
- 数据传输对象(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 类,更简洁、更安全、更现代。
更多推荐

所有评论(0)