【问题标题】:How do I get all Record fields and its values via reflection in Java 17?如何通过 Java 17 中的反射获取所有 Record 字段及其值?
【发布时间】:2021-12-01 20:32:06
【问题描述】:

我有一节课:

class A {
   public final Integer orgId;
}

我用 Java 17 中的记录替换了它:

record A (Integer orgId) {
}

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

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

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

【问题讨论】:

    标签: java reflection java-record java-17


    【解决方案1】:

    您可以使用以下方法:

    RecordComponent[] getRecordComponents()
    

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

    Point.java:

    record Point(int x, int y) { }
    

    RecordDemo.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));
        }
    }
    

    输出:

    10
    

    或者,

    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));
        }
    }
    

    【讨论】:

      【解决方案2】:

      您的classrecord 不等价:记录具有私有 字段。

      Class#getFields() 仅返回 public 字段。

      您可以改用Class#getDeclaredFields()

      【讨论】:

      • getDeclaredFields() 不起作用。返回空数组。
      • @DmitriyDumanskiy 这很奇怪,我只是在本地尝试使用record R(int i) {},但在调用R.class.getDeclaredFields() 时确实得到[private final int R.i]。我在 macOS 上运行 Temurin 的 OpenJDK 17。你运行的是哪个 JDK?
      • getDeclaredFields() 确实有效。
      • @sp00m 你是对的。我用 getFields() 方法放错地方了。
      猜你喜欢
      • 2011-08-20
      • 2020-08-04
      • 2023-04-04
      • 2013-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多