【问题标题】:How does visibility work for Java nested classes?Java 嵌套类的可见性如何工作?
【发布时间】:2015-03-31 19:37:57
【问题描述】:

除了我的 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 visibility


【解决方案1】:

Java Tutorials > Controlling access to members of a class 是我见过的关于访问可见性的最佳摘要之一,但它掩盖了一些关键细节。我认为您要问的问题在 SE 7 的 JLS 的第 6.6.1 节中得到了回答:"Determining Accessibility"

如果 ... public ... 否则,如果 ... protected ... 否则,如果 ... 包访问 ...

否则,成员或构造函数被声明为私有,并且当且仅当它发生在包含成员或构造函数声明的顶级类(第 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();
    }

}

【讨论】:

    【解决方案2】:

    可访问性与访问源相关。首先

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

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

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

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

    这些规则或多或少都在 JLS 的this section 中定义。

    【讨论】:

      猜你喜欢
      • 2018-09-22
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多