Search code examples
javareflectionjava-recordjava-17

How do I get all Record fields and its values via reflection in Java 17?


I had a class:

class A {
   public final Integer orgId;
}

I replaced it with the record in Java 17:

record A (Integer orgId) {
}

Also, I had a code that did a validation via reflection that is working with the regular class, but doesn't work with the Records:

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

What would be the correct way to get the Record object fields and its values via reflection in Java 17?


Solution

  • You can use the following method:

    RecordComponent[] getRecordComponents()
    

    You can retrieve name, type, generic type, annotations, and its accessor method from 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));
        }
    }
    

    Output:

    10
    

    Alternatively,

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