RecordUtil
# 介绍
Java 14 引入了 预览特性 Record(JEP 359),Java 16(2021年3月)正式发布为稳定特性。Record 是一种新型的「数据载体类」,用于简洁、不可变地封装数据,其语法糖极大简化了传统 POJO/DTO 的样板代码:
// 传统方式
public class Point {
private final int x, y;
public Point(int x, int y) { this.x = x; this.y = y; }
public int x() { return x; }
public int y() { return y; }
// equals, hashCode, toString...
}
// Record 方式(JDK 16+)
public record Point(int x, int y) {}
然而,反射操作 Record 类与普通类存在差异:
- Record 没有传统意义上的 Field(字段在字节码层面是 private final)
- 其构造参数顺序与 RecordComponent 严格一致
- 不支持无参构造,必须按组件顺序传参
为此,Hutool v7(面向 JDK 17+ / Jakarta EE 9+ 环境)新增 RecordUtil,专为 java.lang.Record 类型提供轻量级、类型安全的反射支持,补足了通用 bean 工具链对现代 Java 特性的适配。
# 方法
| 方法 | 功能说明 |
|---|---|
isRecord(Class<?>) | 快速判断传入类是否为 Record(利用 Class.isRecord() 原生 API 封装) |
getRecordComponents(Class<?>) | 获取 Record 的全部组件(字段)信息:按声明顺序返回 (name, genericType) 映射数组 |
newInstance(Class<?>, ValueProvider<String>) | 按组件顺序构造 Record 实例,支持泛型类型感知的值注入 |
# 使用
首先我们定义一个Record 类型:
public record User(String name, int age, List<String> tags) {}
# 1.基础判断与元数据获取
Class<User> userClass = User.class;
// 判断是否为 Record
Console.log(RecordUtil.isRecord(userClass)); // true
// 获取组件元数据
var components = RecordUtil.getRecordComponents(userClass);
for (var entry : components) {
Console.log(entry.getKey() + " -> " + entry.getValue());
}
// 输出:
// name -> class java.lang.String
// age -> int
// tags -> java.util.List<java.lang.String>
# 2.动态构造 Record(配合 ValueProvider)
// 假设从配置/JSON 中读取数据
Map<String, Object> data = Map.of(
"name", "Alice",
"age", 25,
"tags", List.of("java", "hutool")
);
// 构造 ValueProvider:按 name + 泛型类型提供值(此处忽略泛型,简化处理)
ValueProvider<String> provider = (name, type) -> {
Object val = data.get(name);
// 实际中可加类型转换:Convert.convert(type, val)
return val;
};
// 动态创建 User 实例
User user = (User) RecordUtil.newInstance(User.class, provider);
Console.log(user); // User[name=Alice, age=25, tags=[java, hutool]]
# 3.与 BeanUtil.toBean() 协同
Map<String, Object> map = Map.of("x", 10, "y", 20);
Point point = BeanUtil.toBean(map, Point.class); // ✅ 自动走 Record 路径
Console.log(point); // Point[x=10, y=20]