【问题标题】:package vs. protected protection with Java reflection使用 Java 反射的包与受保护的保护
【发布时间】:2012-01-22 04:48:38
【问题描述】:

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

考虑以下示例:

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

【问题讨论】:

  • 有趣的问题。对我来说,这听起来像是一个 Java 错误或一个非常深奥的设计决定。

标签: java reflection protected


【解决方案1】:

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

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

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

【讨论】:

  • 是的,JDK 1.00 没有protected 类,所以类文件也没有。你应该会发现你可以从同一个包中访问私有的,甚至是本地的内部类。
猜你喜欢
  • 2010-10-18
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 2011-09-12
  • 2011-04-02
  • 2011-01-23
  • 2012-10-13
相关资源
最近更新 更多