繁体   English   中英

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

[英]How does visibility work for Java nested classes?

我正在尝试学习分配给嵌套类的可见性,除了我的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?
        }
    }
}

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

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

我见过的最佳访问可见性摘要之一是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;       
    }
}

注意:但这不是“文件级别”。 在该文件中声明另一个顶级类(不能是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();
    }

}

可访问性与访问源相关。 第一

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

因此,您在A声明或嵌套在A类中的所有成员都可以在A中访问。

如果您不在A范围内,则无法访问A private成员。 这意味着B无法访问。 由于foobarCDB成员,因此您需要B才能访问它们。 但由于B无法访问,因此您也无法访问它们。

public class Unrelated {
   {
       B b; // nope
       A.B b; // nope
       A.B.C c; // nope 
   }
}

这些规则或多或少都在JLS的这一部分中定义。

暂无
暂无

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

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