访问同一包中的私有内部类

发布于 2024-11-06 22:29:43 字数 849 浏览 1 评论 0原文

我有两个编译单元:

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 方法。但我不明白的是为什么它允许在同一个包中?内部类不受包保护。 Private 不应该在 OuterClass 外部可见,即使它位于同一个包中。我理解有什么问题吗?

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. If they are in separate packages, IllegalAccessException is thrown.

As I understand, exception is thrown because CallingClass cannot invoke private InnerClass methods. But what I do not understand is why is it allowed in the same package? InnerClass is not package protected. Private should not be visible outside OuterClass even if it is in the same package. Do I understand something wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨洒年华 2024-11-13 22:29:43

类的 javap 签名:

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

内部 对于字节码(即运行时)来说,不存在私有类这样的东西。这是编译器维护的虚构。对于反射 API,有一个具有公共成员方法的包可访问类型。

实际的访问修饰符在 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. 

The javap signature for an inner class:

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

When it comes to bytecode (i.e. 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.

Actual access modifiers are defined in the 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. 
七七 2024-11-13 22:29:43

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

Private access modifier is stronger than package one (i.e. not having an access modifier at all in Java). Hence private elements of class - be it fields, methods or inner classes - are accessible only within that class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文