Java also takes care of not being able to access private members, even when doing it via reflection. But constructors, methods, and fields are AccessibleObject
s, which provides a method to flag the member as being accessible although it might be private:
field.setAccessible(true);
Afterwards you can read it and even set a new value on it.
An edit to make it clear. Consider the following simple record class:
public class Record {
private int length;
private String name;
public Record(int length, String name) {
this.length = length;
this.name = name;
}
public int getLength() { return length; }
public String getName() { return name; }
}
And now let's write a reflection test program:
public class ReflectionTest {
public static void main(String[] args) throws Exception {
Record record = new Record(42, "42");
Field[] fields = record.getClass().getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName() + " => " + field.get(record));
}
}
}
This will result in an IllegalAccessException
, as the private fields cannot be accessed. Now change the foreach loop a little:
for (Field field : fields) {
field.setAccessible(true);
System.out.println(field.getName() + " => " + field.get(record));
}
This time you will see expected output:
length => 42
name => 42
Your mistake also was to call the get method on the class and not on the object. This would be like this little modification:
for (Field field : fields) {
field.setAccessible(true);
System.out.println(field.getName() + " => " + field.get(record.getClass()));
}
This time you will see an IllegalArgumentException
(not an IllegalAccessException
).