495. Java 反射 - 获取 Record 组件信息
Record 与普通类最大的不同之一,就是引入了 record component(记录组件)。
- 每个
record在声明时,都会定义一组组件(如字段名、类型)。 - 编译器会为这些组件自动生成构造器和访问器方法。
- Reflection API 提供了一个专门的类
RecordComponent来描述这些组件。
1. RecordComponent API
每个组件都可以通过 RecordComponent 对象来访问,它提供了如下方法:
| 方法 | 说明 |
|---|---|
getDeclaringRecord() |
返回声明该组件的 record 类 |
getName() |
返回组件的名称 |
getType() |
返回组件的类型(Class 对象) |
getGenericType() |
返回泛型类型(Type 对象) |
getAccessor() |
返回访问该组件的 getter 方法 |
getGenericSignature() |
返回组件的泛型签名(如有) |
要获取所有组件,可以调用 Class.getRecordComponents(),它返回一个 RecordComponent[] 数组。
2. 示例:Point 记录类
假设我们有如下记录类:
public record Point(int x, int y) {
public Point() {
this(0, 0);
}
}
我们使用反射来获取 x 组件的信息:
Class<?> c = Point.class;
RecordComponent[] components = c.getRecordComponents();
RecordComponent comp = components[0]; // 取第一个组件:x
System.out.println("Declaring record: " + comp.getDeclaringRecord());
System.out.println("name = " + comp.getName());
System.out.println("accessor = " + comp.getAccessor());
System.out.println("type = " + comp.getType());
System.out.println("genericType = " + comp.getGenericType());
System.out.println("genericSignature = " + comp.getGenericSignature());
3. 输出结果与解释
运行结果类似如下:
Declaring record: class org.devjava.Point
name = x
accessor = public int org.devjava.Point.x()
type = int
genericType = int
genericSignature = null
🔎 逐项解析:
-
Declaring record
- 显示
Point类是x组件的声明者。
- 显示
-
name
- 组件的名字,即
x。
- 组件的名字,即
-
accessor
- 访问器方法:
public int org.devjava.Point.x()。 - 注意:编译器会为每个组件自动生成一个 getter,名字与组件一致。
- 访问器方法:
-
type / genericType
- 类型是
int,没有泛型,所以type和genericType一致。
- 类型是
-
genericSignature
- 返回泛型签名,如果没有泛型则为
null。
- 返回泛型签名,如果没有泛型则为
4. 示例:带泛型的 Record
public record Box<T>(T value) {}
反射结果:
name = value
type = java.lang.Object
genericType = T
📌 要点:
-
getType()返回的是擦除后的类型(Object)。 -
getGenericType()保留了泛型声明信息(T)。
5. 小结
-
RecordComponent 是 Reflection API 的新成员,专门用于操作
record的组件信息。 - 你可以通过
getRecordComponents()获取所有组件,并查询它们的名称、类型和访问器。 -
泛型信息需要用
getGenericType()才能保留,getType()只会返回擦除后的原始类型。 - 学会区分 源代码声明的类型 和 运行时实际类型,这在调试和框架开发中尤为重要。