如何在 Java 17 中通过反射获取所有记录字段及其值?

Dmi*_*kiy 13 java reflection java-record java-17

我上过一堂课:

class A {
   public final Integer orgId;
}
Run Code Online (Sandbox Code Playgroud)

我将其替换为Java 17中的记录:

record A (Integer orgId) {
}
Run Code Online (Sandbox Code Playgroud)

另外,我有一个通过反射进行验证的代码,该代码适用于常规类,但不适用于记录:

Field[] fields = obj.getClass().getFields(); //getting empty array here for the record
for (Field field : fields) {
}
Run Code Online (Sandbox Code Playgroud)

在 Java 17 中通过反射获取 Record 对象字段及其值的正确方法是什么?

Arv*_*ash 20

您可以使用以下方法:

RecordComponent[] getRecordComponents()
Run Code Online (Sandbox Code Playgroud)

您可以从 中检索名称、类型、泛型类型、注释及其访问器方法RecordComponent

点.java:

record Point(int x, int y) { }
Run Code Online (Sandbox Code Playgroud)

记录演示.java:

import java.lang.reflect.RecordComponent;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class RecordDemo {
    public static void main(String args[]) throws InvocationTargetException, IllegalAccessException {
        Point point = new Point(10,20);
        RecordComponent[] rc = Point.class.getRecordComponents();
        System.out.println(rc[0].getAccessor().invoke(point));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

10
Run Code Online (Sandbox Code Playgroud)

或者,

import java.lang.reflect.RecordComponent;
import java.lang.reflect.Field;

public class RecordDemo {
    public static void main(String args[]) 
            throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException {
        Point point = new Point(10, 20);
        RecordComponent[] rc = Point.class.getRecordComponents();      
        Field field = Point.class.getDeclaredField(rc[0].getAccessor().getName());  
        field.setAccessible(true); 
        System.out.println(field.get(point));
    }
}
Run Code Online (Sandbox Code Playgroud)