包与受Java保护的反射保护
为什么我可以使用反射来实例化一个内部受保护的类,但不是具有程序包级保护的内部类? 我不认为任何一种都可以在包装外面使用。
考虑下面的例子:
package dummy;
public class ClassContainer {
protected static class InnerProtected {
public InnerProtected() {}
}
static class InnerDefault {
public InnerDefault() {}
}
private class InnerPrivate {
public InnerPrivate() {}
}
}
package driver;
public class DriverClass {
public static void main(String[] args) throws Exception {
Class.forName("dummy.ClassContainer$InnerProtected").newInstance();
Class.forName("dummy.ClassContainer$InnerDefault").newInstance();
Class.forName("dummy.ClassContainer$InnerPrivate").newInstance();
}
}
注意这两个类是在不同的包中。
main中的第一行(实例化InnerProtected)起作用。
第二行(实例化InnerDefault)引发此异常:
Exception in thread "main" java.lang.IllegalAccessException: Class driver.DriverClass can not access a member of class dummy.ClassContainer$InnerDefault with modifiers "public"
由于驱动程序是一个不同于类定义的软件包,不应该同时尝试实例化这些类吗?
(对于它的价值:试图实例化InnerPrivate失败,正如我所期望的那样:
Exception in thread "main" java.lang.InstantiationException: dummy.ClassContainer$InnerPrivate
真的, javap
报告InnerProtected
是public
编译的,而其他成员类是包私有的。
我相信这是由于需要使它从不同包中的ClassContainer
子类可见。 在这种情况下,VM可能无法处理访问控制规则,以便在编译器级别进行处理。
但是,请注意,如果您省略这些类的构造函数声明,则其生成的构造函数将具有其预期的可见性,即分别为protected
,default和private
。