简体   繁体   English

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

[英]Accessing private inner class in the same package

I have two compilation units: 我有两个编译单元:

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

If they are in the same package, everything works and "response: testing123" is printed. 如果它们在同一个包中,一切正常并且打印出“response:testing123”。 If they are in separate packages, IllegalAccessException is thrown. 如果它们位于单独的包中,则抛出IllegalAccessException。

As I understand, exception is thrown because CallingClass cannot invoke private InnerClass methods. 据我所知,抛出异常是因为CallingClass无法调用私有的InnerClass方法。 But what I do not understand is why is it allowed in the same package? 但我不明白为什么在同一个包中允许它? InnerClass is not package protected. InnerClass不受包保护。 Private should not be visible outside OuterClass even if it is in the same package. 即使它在同一个包中,也不应在OuterClass外看到Private。 Do I understand something wrong? 我理解错了吗?

The javap signature for an inner class: 内部类的javap签名:

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

When it comes to bytecode (ie runtime) there is no such thing as a private class. 说到字节码(即运行时),就没有私有类这样的东西。 This is a fiction maintained by the compiler. 这是编译器维护的虚构。 To the reflection API, there's a package-accessible type with a public member method. 对于反射API,有一个包可访问类型,带有公共成员方法。

Actual access modifiers are defined in the JVM spec : 实际访问修饰符在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. 

Private access modifier is stronger than package one (ie not having an access modifier at all in Java). 私有访问修饰符比包一强(即在Java中根本没有访问修饰符)。 Hence private elements of class - be it fields, methods or inner classes - are accessible only within that class. 因此,类的私有元素 - 无论是字段,方法还是内部类 - 只能在该类中访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM