简体   繁体   English

类无法使用来自不同包的反射来访问其自己的受保护的成员变量

[英]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和两个都扩展ABC A and B are in the same package and C is in a different package. AB在同一包装中, C在不同的包装中。

Both, B and C have a protected member variable. BC都有受保护的成员变量。 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不是BC的子类,因此子类的成员变量的可见性在这里不起作用。

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 . 但是,由于BA在同一包中,并且成员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.

相关问题 为什么继承类的实例无法访问不同包中的基类的受保护成员 - Why an instance of inherited class can't access to protected member of base class in different package 当子类位于不同的包中时,为什么我的子类不能访问其超类的受保护变量? - Why can't my subclass access a protected variable of its superclass, when it's in a different package? 无法从不同jar中的同一个包访问超类的受保护成员 - Can't access protected member of superclass from same package in different jar 在不使用public的情况下访问不同包中的受保护的类变量 - Access protected class variable in different package without using public 有没有办法在没有反射的情况下从不同的运行时包访问受保护的类成员? - Is there a way to access protected class members from different runtime package without reflection? 使用反射访问受保护的类 - access protected class using reflection 使用反射访问成员变量 - Access a member variable using reflection 受保护的为什么不能在不同的包子类中访问? - protected can't access in different package subclass why? 从不同包中的不同类访问变量? - Access variable from a different class in a different package? 程序包访问类|(在公共和受保护之间有所不同) - package access class |(different between public and protected)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM