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

时间:2011-05-10 13:57:49

标签: java reflection visibility inner-classes

我有两个编译单元:

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();
        }
    }
}

如果它们在同一个包装中,一切正常并且打印出“response:testing123”。如果它们位于不同的包中,则抛出IllegalAccessException。

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

2 个答案:

答案 0 :(得分:8)

内部类的javap签名:

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

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

实际访问修饰符在JVM spec

中定义
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. 

答案 1 :(得分:-1)

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