2
public class SuperClass{
    public SuperClass(){
        System.out.println("Super class");
    }
}

public class SubClass extends SuperClass{
    int i;
    {
        i=10;
    }
    public SubClass(){
        System.out.println("Subclass");
    }
    public static void main(String[] args){
        SubClass sc = new SubClass();
    }
}

我在所有可能的地方进行了调试,我首先看到创建实例时,它首先进入 SuperClass 构造函数并打印 Super Class ,然后才进入实例变量,然后是初始化块,最后是 SubClass 构造函数并打印子类。

但是,我在某个地方读到过,在子类构造函数内部是默认调用 super() 的地方,也就是当它转到超类构造函数的时候!!!

4

3 回答 3

9

SubClass()构造函数隐式如下所示:

 public SubClass(){
    super();
    {
      i=10;
    }
    System.our.println("Subclass");
 }

根据JLS 第 12.5 节

就在作为结果返回对新创建对象的引用之前,使用以下过程处理指示的构造函数以初始化新对象:

  1. 将构造函数的参数分配给此构造函数调用的新创建的参数变量。

  2. 如果此构造函数以同一类中另一个构造函数的显式构造函数调用(第 8.8.7.1 节)开始(使用 this),则评估参数并使用这五个相同的步骤递归地处理该构造函数调用。如果该构造函数调用突然完成,则此过程出于相同原因而突然完成;否则,继续执行步骤 5。

  3. 此构造函数不以显式构造函数调用同一类中的另一个构造函数开始(使用 this)。如果此构造函数用于 Object 以外的类,则此构造函数将以显式或隐式调用超类构造函数(使用 super)开始。使用这五个相同的步骤递归地评估超类构造函数调用的参数和过程。如果该构造函数调用突然完成,则此过程出于相同的原因突然完成。否则,继续执行步骤 4。

  4. 执行该类的实例初始化程序和实例变量初始化程序,将实例变量初始化程序的值分配给相应的实例变量,按照它们在源代码中以文本形式出现的从左到右的顺序。如果执行这些初始化程序中的任何一个导致异常,则不会处理更多初始化程序,并且此过程会突然完成相同的异常。否则,继续执行步骤 5。

  5. 执行此构造函数的其余部分。如果该执行突然完成,则此过程出于同样的原因突然完成。否则,此过程正常完成。

于 2013-06-10T11:07:42.497 回答
5

好吧,那是因为您的SubClass构造函数实际上看起来像这样:

public SubClass() {
    super();
    {
       i=10;
    }
    System.out.println("Subclass");
}

如果您不调用super(); 显式地,编译器会隐式地为你做这件事。这意味着首先SuperClass调用构造函数,然后调用`System.out.println("Subclass");

此外,super()必须是构造函数中的第一条语句。

SuperClass 您可以通过创建私有的构造函数来检查所有这些(也可以在单独的文件中)。SubClass编译器会在构造函数中显示一个错误,指出SuperClass.

于 2013-06-10T11:06:40.167 回答
1

构造函数总是调用super(). 那是隐含的。

阅读文档

如果构造函数没有显式调用超类构造函数,Java 编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会出现编译时错误。Object 确实有这样的构造函数,所以如果 Object 是唯一的超类,则没有问题。

于 2013-06-10T11:08:31.643 回答