使用Java反射打包和受保护的保护

Zac*_*ack 7 java reflection protected

为什么我可以使用反射来实例化内部受保护的类,而不是使用包级保护的内部类?我不认为任何一种都可以在包装外进行访问.

请考虑以下示例:

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();
   }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这两个类位于不同的包中.

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"
Run Code Online (Sandbox Code Playgroud)

由于驱动程序是与类定义不同的包,因此实例化类的尝试不应该失败吗?

(对于它的价值:试图实例化InnerPrivate失败,如我所料:

Exception in thread "main" java.lang.InstantiationException: dummy.ClassContainer$InnerPrivate
Run Code Online (Sandbox Code Playgroud)

axt*_*avt 4

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

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

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