可见性如何适用于Java嵌套类?

dje*_*lin 10 java visibility

我正在尝试学习分配给嵌套类的可见性,除了我的IDE对我大吼大叫之外我还要做什么.这可能会变得任意复杂,所以我需要理解一般规则.

public class A {
    private static class B {
        public int foo; // accessible in A?
        private int bar; // accessible in A?
        public static class C { // accessible in A? everywhere?
        }
        private static class D { // accessible in A?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,修饰符似乎在"文件"级别解析,而不是在封装类的级别.一旦有一件事是私人的,其中的任何东西都是私人的.

这个或技术解释的实际机制是什么?这是在某处记录的还是我只需要阅读JLS?

And*_*own 9

我见过的最佳访问可见性摘要之一是Java教程>控制对类成员的访问,但它掩盖了一些关键细节.我认为你问的问题在SE7的JLS第6.6.1节中回答:"确定可访问性"

如果......公共......否则,如果...受保护...否则,如果...包访问...

否则,成员或构造函数被声明为private,并且当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问.

如果你仔细阅读:

  1. 任何访问
  2. 在顶级课程的主体内
  3. 到另一个private(不是包私有 - 那是不同的)成员
  4. 无论嵌套的深度如何
  5. 是允许的

因此:任何深度的私有嵌套类中的任何成员都可以顶级类的主体内的任何位置访问(包括在其他嵌套的兄弟类中).但是,私有嵌套类及其中的任何成员对其他顶级类是不可见的.

例如:

public class A {
    private static class B {
        public int foo; // accessible in A and P
        private int bar; // accessible in A and P   
        public static void test(){
            P p = new P();
            p.foo = 1; p.bar = 1;
        }
    }
    private static class P {
        public int foo; // accessible in A and B
        private int bar; // accessible in A and B   
        public static void test(){
            B b = new B();
            b.foo = 1; b.bar = 1;
        }
    }
    public static void test(){
        B b = new B();
        b.foo = 1; b.bar = 1;
        P p = new P();
        p.foo = 1; p.bar = 1;       
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:但这不是"文件级别".在该文件中声明另一个顶级类(不可能public- 每个文件只允许其中一个),并且它无法看到那些相同的嵌套private成员.

class X {
    public static void test() {
        // all of these statements fail ...
        A.B b = new A.B();
        b.foo = 1; b.bar = 1; 
        b.test();
        A.P p = new A.P();
        p.foo = 1; p.bar = 1;  
        p.test();
    }

}
Run Code Online (Sandbox Code Playgroud)