与基类构造函数相比,Java隐式构造函数何时被调用?

5

如果我有这样的内容:

public class SuperClass
{
    SuperClass()
    {
        x = true;
    }
    public boolean x;
}

public class SubClass extends SuperClass
{
    SubClass()
    {
        x = false;
    }
}

我最终创建了一个SubClass对象。那么x是true还是false?从http://docs.oracle.com/javase/specs/jls/se5.0/html/execution.html#12.5中可以看出,它将是false。


你的示例中基类和超类之间没有连接。 - Maroun
在你的例子中,SuperClassBaseClass是独立的。 - August
5
你的类名让人困惑,BaseClass 应该继承 SuperClass 吧?那么它的名字是不是应该更像 SubClass 或者 DerivedClass - Pshemo
2个回答

10

来自 《Java语言规范》第12.5节(重点部分已加粗):

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

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

  2. 如果此构造函数以同一类中的另一个构造函数的显式构造函数调用(§8.8.7.1)(使用this)开头,则使用相同的五个步骤递归地评估参数并处理该构造函数调用。如果该构造函数调用异常终止,则出于同样的原因,本过程也异常终止;否则,继续执行第5步。

  3. 此构造函数没有以本类中另一个构造函数的显式构造函数调用(使用this)开头。如果此构造函数是其他类的构造函数,则此构造函数将以超类构造函数的显式或隐式调用(使用super)开头。使用相同的五个步骤递归地评估参数并处理该超类构造函数调用。如果该构造函数调用异常终止,则出于同样的原因,本过程也异常终止。否则,继续执行第4步。

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

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

所以首先会调用父类的构造函数(第3步),将 x 设置为 true。在超类的构造函数处理和递归地使用相同的步骤之后,子类的构造函数体将其设置为 false(第5步)。


7
在原始版本的代码中[*],这两个类没有关联,因为没有声明或继承x,所以BaseClass甚至无法编译。
如果你将BaseClass设置为SuperClass的子类,则x将为false,因为SuperClass的构造函数将在BaseClass之前运行。
[*] 在有人编辑问题添加extend SuperClass之前。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接