I have three classes: one base class A and two classes B and C that both extend A. A and B are in the same package and C is in a different package.
Both, B and C have a protected member variable. A has a method (lets call it reflect) that uses reflection and a string input to accesses a field with this name of a subclass via the this pointer.
Calling reflect from a B object is fine, but calling it from a C object results in an IllegalAccessException. I can not understand this exception, because this means that C has no access rights to access its own member variable. Why doesn't java allow this reflection?
Here is a MWE to clarify what I mean:
In parent/A.java:
package Parent;
public abstract class A {
public Object reflect(String parameter) throws NoSuchFieldException, IllegalAccessException{
Class cl = getClass();
return cl.getDeclaredField(parameter).get(this);
}
}
In parent/B.java:
package Parent;
public class B extends A{
protected Integer b;
public B(Integer b){
this.b = b;
}
}
In parent/child/C.java:
package Parent.Child;
import Parent.A;
public class C extends A{
protected Integer c;
public C(Integer c){
this.c = c;
}
}
and a small main:
import Parent.A;
import Parent.B;
import Parent.Child.C;
public class test {
public static void main(String args[]) {
B j1 = new B(10);
C j2 = new C(20);
try{
Integer b_copy = (Integer)j1.reflect("b");
System.out.println(b_copy); // prints "10"
Integer c_copy = (Integer)j2.reflect("c"); // throws java.lang.IllegalAccessException: Class Parent.A can not access a member of class Parent.Child.C with modifiers "protected"
System.out.println(c_copy);
} catch (NoSuchFieldException | IllegalAccessException e) {
System.out.println(e);
}
}
}
Thank you very much!
Reflection allows you to bypass the access protection mechanism but you must explicitly instruct it to do so:
package Parent;
public abstract class A {
public Object reflect(String parameter) throws NoSuchFieldException, IllegalAccessException{
Class cl = getClass();
java.lang.reflect.Field f = cl.getDeclaredField(parameter);
f.setAccessible(true);
return f.get(this);
}
}
In particular, you may be having the issue with C because you're actually accessing C's protected variable from A since that's where you're performing the reflective call. You'd get the same access violation if you tried accessing C's field directly from A.reflect().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With