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?
CodePudding user response:
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));
}
}
CodePudding user response:
Your class
and record
aren't equivalent: records have private fields.
Class#getFields()
returns public fields only.
You could use Class#getDeclaredFields()
instead.