繁体   English   中英

Java私有构造函数可见性

[英]Java private constructors visibility

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

请考虑以下示例:

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
    }
  }
}

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

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

[...]

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

  • [...]

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

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

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

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

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

所以这里的诀窍可能如下:

你不能访问foo因为它被声明为私有所以你不能在C中继承它。

但是,如评论中所述,您可以访问super.foo(); 因为super指的是在同一顶级类中声明的类型(请参阅JLS 6.6.1)。

然后诀窍是调用super(s)可以被视为调用super.<init>(s)最终与super.foo()情况相同

Foo()方法在类C中是不可访问的,因为foo()方法是私有的,而私有方法不能继承到基类。

对于构造者来说,构造函数永远不会被隐藏。 另外,我编译了这段代码:

 class Vehicle{  
        int speed=50;  
        private Vehicle()
        {
           System.out.println("Private Vehicle constructor");
        }
    } 
    public class Bike4 extends Vehicle{  
        int speed=100;   
    Bike4()
    {
        super();
         System.out.println("Hi I n constructor");
    }
  void display(){  
   System.out.println(super.speed);//will print speed of Vehicle now  
  }  
  public static void main(String args[]){  
   Bike4 b=new Bike4();  
   b.display();  

}  
}  

并获得编译时错误:Vehicle()在Vehicle super()中具有私有访问权限; ^这清楚地表明无法使用super访问私有构造函数。 如果我们能够初始化或访问私有构造函数,那么创建私有构造函数的重点是什么。

暂无
暂无

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

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