Java私有构造函数可见性

Mic*_*eam 31 java constructor private

我试着理解为什么在谈论构造函数时类成员的可访问性之间存在差异.

请考虑以下示例:

class A {
  static class B {  
    private B(String s) {}
    private void foo() {}
  }
  static class C extends B {
    public C(String s) {
      super(s); // call B(String), which is private, and obviously accessible
    }
    void bar() {
      foo(); // compilation error (symbol unknown), as B.foo() is private
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

私人的私人成员A不应该是私人的B.对于字段和方法,情况确实如此,但似乎构造函数不遵循相同的规则.

从JLS-8(6.6.1.确定可访问性),我们可以阅读:

[...]

只有在类型可访问且声明成员或构造函数允许访问时,才能访问引用类型的成员(类,接口,字段或方法)或类类型的构造函数:

  • [...]

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

任何人都可以解释为什么构造函数可以访问C,即使在声明时private

Wil*_*lQu 25

该方法foo()是私有的,因此您不会继承它,也不能直接从C类中调用它.

但是,您可以看到私有方法和构造函数,B因为所有内容都在同一个包含类中声明,并使用它们访问它们super,这就是为什么super()有效.以同样的方式,您可以访问foo使用super.foo().

请注意,您可以重新定义新的foo方法C,但此方法不会覆盖B.foo().