私有构造函数在类中的用法

时间:2011-03-19 07:47:39

标签: java

如果有私有构造函数,JVM是否会插入对超级构造函数的调用?

我指的是私有构造函数中的super()调用。

class Alpha {
    static String s="";
    protected Alpha(){
        s+="alpha";
    }
}

class SubAlpha extends Alpha{
    private SubAlpha(){
        s+="sub";
    }
}

class SubSubAlpha extends Alpha{
    private SubSubAlpha(){
        s+="subsubAlpha";
    }

    public static void main(String[] args){
        new SubSubAlpha();
        System.out.print(s);   
    }
}

这里我没有得到任何编译错误。这里的SubSubAlpha类有私有构造函数。该编译器是否插入super()调用,如果是这样,SubAlpha类中会发生什么。即使有私人建设者。如果没有访问,继承树如何继续到顶部。

5 个答案:

答案 0 :(得分:8)

  

如果有私有构造函数,JVM是否会调用超级构造函数?

超级构造函数总是被调用。 (你不能实例化一个类,也不能同时实例化超类。)

如果您没有自己明确地执行此操作,则无论构造函数是私有还是公共,都会为您插入隐式调用。


要挑剔:它实际上不是插入它的JVM,而是Java编译器:

public class Test {
    private Test() {
    }
}

编译成

private Test();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

答案 1 :(得分:4)

是。如果没有明确的super()super构造函数调用,则私有构造函数具有隐式this调用。在这方面,它与其他构造者没有什么不同。当然,为了编译,超类必须有一个从类中可见的无参数构造函数。

但是,如果构造函数是private,则它不能从子类中调用 ...或者除了类本身之外的任何其他代码。

答案 2 :(得分:4)

您没有收到编译时错误的原因是您的类层次结构不是您认为的那样。我想你的意思是:

class SubSubAlpha extends Alpha {

是这样的:

class SubSubAlpha extends SubAlpha {

......此时你确实会遇到编译时错误。

(换句话说,是的, 总是调用超级构造函数。)

答案 3 :(得分:1)

这是Java Programmer's SourceBook的一个很好的例子。由于构造函数在调用时打印,因此您将立即看到调用的顺序。它来自Thinking in Java。

//: Cartoon.java
// Constructor calls during inheritance

class Art {
  Art() {
    System.out.println("Art constructor");
  }
}

class Drawing extends Art {
  Drawing() {
    System.out.println("Drawing constructor");
  }
}

public class Cartoon extends Drawing {
  Cartoon() {
    System.out.println("Cartoon constructor");
  }
  public static void main(String[] args) {
    Cartoon x = new Cartoon();
  }
} ///:~ 

此程序的输出显示自动调用:

艺术建设者
图纸构造函数
卡通构造函数

答案 4 :(得分:-1)

Ya,你可以使用super()来使用超类中的函数和属性。它和普通的java一样