在同一个包中访问私有内部类

我有两个编译单元:

public class OuterClass{ private static class InnerClass{ public String test(){ return "testing123"; } } public static void main( String[] args ){ new CallingClass().test( new InnerClass() ); } } public class CallingClass{ public void test( Object o ){ try{ Method m = o.getClass().getMethod( "test" ); Object response = m.invoke( o ); System.out.println( "response: " + response ); } catch( Exception e ){ e.printStackTrace(); } } } 

如果它们在同一个包中,则一切正常并打印出“响应:testing123”。 如果它们位于单独的包中,则抛出IllegalAccessException。

据我所知,抛出exception是因为CallingClass无法调用私有的InnerClass方法。 但我不明白为什么在同一个包中允许它? InnerClass不受包保护。 即使它在同一个包中,也不应在OuterClass外看到Private。 我理解错了吗?

内部类的javap签名:

 class modifiers.OuterClass$InnerClass extends java.lang.Object{ final modifiers.OuterClass this$0; public java.lang.String test(); } 

说到字节码(即运行时),就没有私有类这样的东西。 这是编译器维护的虚构。 对于reflectionAPI,有一个包可访问类型,带有公共成员方法。

实际访问修饰符在JVM规范中定义:

 Flag Name Value Interpretation ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package. ACC_FINAL 0x0010 Declared final; no subclasses allowed. ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the invokespecial instruction. ACC_INTERFACE 0x0200 Is an interface, not a class. ACC_ABSTRACT 0x0400 Declared abstract; may not be instantiated. 

私有访问修饰符比包一强(即在Java中根本没有访问修饰符)。 因此,类的私有元素 – 无论是字段,方法还是内部类 – 只能在该类中访问。