我有三个类:一个基类 A
和两个类 B
和 C
都扩展了 A
. A
和B
在同一个包中,C
在不同的包中。
B
和C
都有一个 protected 成员变量。 A
有一个方法(我们称它为 reflect
),它使用反射和字符串输入通过 this
访问子类的这个名称的字段> 指针。
从 B
对象调用 reflect
没问题,但从 C
对象调用它会导致 IllegalAccessException。我无法理解这个异常,因为这意味着 C
没有访问权限来访问它自己的成员变量。为什么 java 不允许这种反射?
这是一个 MWE 来阐明我的意思:
在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);
}
}
在parent/B.java
中:
package Parent;
public class B extends A{
protected Integer b;
public B(Integer b){
this.b = b;
}
}
在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;
}
}
和一个小主:
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);
}
}
}
非常感谢!
最佳答案
反射允许您绕过访问保护机制,但您必须明确指示它这样做:
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);
}
}
特别是,您可能遇到 C
的问题,因为您实际上是从 A
访问 C
的 protected 变量,因为那是你在哪里执行反射调用。如果您尝试直接从 A.reflect()
访问 C
的字段,您会遇到同样的访问冲突。
关于java - 类无法使用来自不同包的反射访问其自己的 protected 成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48731951/