包与 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
Why can I use reflection to instantiate a inner protected class, but not an inner class with package-level protection? I wouldn't think either would be accessible outside the package.
Consider the following example:
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();
}
}
Notice that the two classes are in different packages.
The first line in main (which instantiates InnerProtected) works.
The second line (which instantiates InnerDefault) throws this exception:
Exception in thread "main" java.lang.IllegalAccessException: Class driver.DriverClass can not access a member of class dummy.ClassContainer$InnerDefault with modifiers "public"
Since the driver is an a different package than the class definitions, shouldn't both attempts at instantiating the classes fail?
(For what it's worth: Attempting to instantiate InnerPrivate fails as I would expect:
Exception in thread "main" java.lang.InstantiationException: dummy.ClassContainer$InnerPrivate
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实际上,
javap
报告InnerProtected
被编译为public
,而其他成员类是包私有的。我相信这是由于需要使其对来自不同包的 ClassContainer 的子类可见而引起的。在这种情况下,VM 可能无法处理访问控制规则,因此它们在编译器级别进行处理。
但请注意,如果您省略这些类的构造函数声明,则它们生成的构造函数将具有预期的可见性,即分别为
protected
、default 和private
。Really,
javap
reports thatInnerProtected
is compiled aspublic
, whereas other member classes are package-private.I believe it's caused by the need to make it visible to subclasses of
ClassContainer
from different packages. Perhaps VM cannot handle access control rules in this case, so that they are handled at compiler level.Note, however, that if you omit constuctor declarations for these classes their generated constructors would have their expected visililities, that is
protected
, default andprivate
respectively.