包与 Java 反射的受保护保护

发布于 2024-12-21 09:29:25 字数 1226 浏览 3 评论 0原文

为什么我可以使用反射实例化内部受保护类,但不能实例化具有包级保护的内部类?我不认为任何一个都可以在包之外访问。

请考虑以下示例:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦冥 2024-12-28 09:29:25

实际上,javap 报告 InnerProtected 被编译为 public,而其他成员类是包私有的。

我相信这是由于需要使其对来自不同包的 ClassContainer 的子类可见而引起的。在这种情况下,VM 可能无法处理访问控制规则,因此它们在编译器级别进行处理。

但请注意,如果您省略这些类的构造函数声明,则它们生成的构造函数将具有预期的可见性,即分别为 protected、default 和 private

Really, javap reports that InnerProtected is compiled as public, 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 and private respectively.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文