[英]Class can't access its own protected member variable using reflection from different package
I have three classes: one base class A
and two classes B
and C
that both extend A
. 我有三个类:一个基类
A
和两个都扩展A
类B
和C
A
and B
are in the same package and C
is in a different package. A
和B
在同一包装中, C
在不同的包装中。
Both, B
and C
have a protected member variable. B
和C
都有受保护的成员变量。 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. A
具有使用反射和字符串输入通过this
指针访问具有此子类名称的字段的方法(我们称其为reflect
)。
Calling reflect
from a B
object is fine, but calling it from a C
object results in an IllegalAccessException. 从
B
对象调用reflect
是可以的,但是从C
对象调用reflect
导致IllegalAccessException。 I can not understand this exception, because this means that C
has no access rights to access its own member variable. 我无法理解此异常,因为这意味着
C
没有访问权限来访问其自己的成员变量。 Why doesn't java allow this reflection? Java为什么不允许这种反射?
Here is a MWE to clarify what I mean: 这是MWE,以阐明我的意思:
In parent/A.java
: 在
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
: 在
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
: 在
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. 特别是,您可能会遇到
C
问题,因为您实际上是从A
访问C
的受保护变量,因为这是您在执行反射调用的地方。 You'd get the same access violation if you tried accessing C
's field directly from A.reflect()
. 如果尝试直接从
A.reflect()
访问C
的字段, A.reflect()
遇到相同的访问冲突。
The exception is quite clear: 异常很明显:
java.lang.IllegalAccessException: Class Parent.A can not access a member of class Child.C with modifiers "protected"
The method is running under the namespace (=package) of class A. 该方法在类A的名称空间(=程序包)下运行。
The protected
access modifier implies package-visibility. protected
访问修饰符表示程序包可见性。
Notice that A
is not a subclass of B
or C
, therefore the visibility of member variables for subclasses plays no role here. 注意,
A
不是B
或C
的子类,因此子类的成员变量的可见性在这里不起作用。
However, since B
is in the same package as A
, and the member b
is marked as protected
, it is also package-visible, and therefore can be accessed from A
. 但是,由于
B
与A
在同一包中,并且成员b
被标记为protected
,因此它也是包可见的,因此可以从A
访问。
For C
, this is not the case, because A
is neither a subclass of C
, nor is C
in the same package as A
. 对于
C
,不是这种情况下,因为A
既不的一个子类C
,也不是C
在相同的封装中A
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.