Java 在构造函数中调用this()会隐式调用super()吗?

Java 在构造函数中调用this()会隐式调用super()吗?,java,class,constructor,Java,Class,Constructor,我试图理解 为什么this()和super()不能一起使用? 我已经阅读了这里关于stackoverflow的许多相关讨论,并且理解了很多事情。但我还有一个困惑就是 在构造函数中调用this()会隐式调用super() 考虑一下这段代码 class Top { int z; Top() { System.out.println("Top default constructor"); } } class A extends Top { in

我试图理解

为什么this()和super()不能一起使用?

我已经阅读了这里关于stackoverflow的许多相关讨论,并且理解了很多事情。但我还有一个困惑就是

在构造函数中调用this()会隐式调用super()

考虑一下这段代码

class Top
{
    int z;
    Top()
    {
        System.out.println("Top default constructor");
    }

}
class A extends Top
{
    int x;
    A(int num)
    {
        x=num;
        System.out.println("A parameterized constructor");
    }
    A()
    {
        this(5);
        System.out.println("A default constructor");
    }
    public static void main(String arg[])
    {
        new A();
    }
}
输出为:

顶级默认构造函数

参数化构造函数

默认构造函数

我不希望输出“Top default constructor”中出现第一行,因为没有super()调用,隐式或显式

所以,可能有一些东西我误解了。请解释。

在构造函数中调用
this()
会调用同一类的另一个构造函数。另一个构造函数将调用
super()
构造函数(隐式或显式),这就是为什么不能在同一个构造函数中同时调用
this()
super()
,因为这将导致调用两个
super()
构造函数

请注意,每当我编写
this()
super()
时,我并不一定意味着调用无参数构造函数(除了对
super()
的隐式调用,正如Joeblade所评论的那样,它总是调用超类的无参数构造函数)。两个调用都可以有参数

在您的代码示例中,
A()
构造函数调用
A(int)
构造函数(这就是
this(5)
所做的),它隐式调用
Top()
(无参数)构造函数。

此(5)
调用
A(int num)
它隐式调用
super()

在构造函数中调用this()会隐式调用super()吗

在构造函数中调用
this()
将调用该类的零参数构造函数。如果该类的零参数构造函数没有对
super(…)
的显式调用,那么是的,将有对零参数
super()
构造函数的隐式调用。如果类中的zero-args构造函数显式调用了其他
super
签名,那么当然会这样做

一般来说,这对于构造函数是正确的。在
A
类中,由于
A(int)
构造函数没有任何调用
this()
super()
,因此隐式
super()
已完成

我没想到输出“Top default constructor”中会出现第一行,因为没有
super()
调用,隐式或显式调用

是的,有-一个隐含的。:-)


基本规则是:某些基类构造函数必须在派生类中的代码运行之前运行。这就是为什么调用
this(…)
super(…)
必须是构造函数中的第一件事。如果构造函数没有显式调用
super(…)
,则总是隐式调用
super()
(不带参数)。

这在上的Java语言规范一节中进行了解释,重点是用粗体标记的超类构造函数:

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

  • 为此构造函数调用将构造函数的参数分配给新创建的参数变量

  • 如果此构造函数以同一类中另一个构造函数的显式构造函数调用(§8.8.7.1)开始(使用此构造函数),则使用相同的五个步骤递归地评估该构造函数调用的参数和过程。如果构造函数调用突然完成,那么这个过程也会因为同样的原因突然完成;否则,继续执行步骤5

  • 此构造函数不会以同一类中另一个构造函数的显式构造函数调用开始(使用此函数)如果此构造函数用于对象以外的类,则此构造函数将以超类构造函数的显式或隐式调用(使用super)开始。使用相同的五个步骤递归地评估超类构造函数调用的参数和过程。如果构造函数调用突然完成,那么此过程也会因为同样的原因突然完成。否则,继续执行步骤4

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

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

  • 因此,在您的例子中,当使用
    this(5)
    调用构造函数
    A(int num)
    时,步骤3指示它隐式调用超类构造函数,递归地应用相同的过程


    请注意,您可以通过调试构造函数调用序列来完成此过程。

    Simpe规则:构造函数中的第一个语句必须是对另一个构造函数的调用-在同一类(
    this(…)
    )中或在父类(
    super(…)
    )中。如果省略显式构造函数调用,编译器将自动生成对
    super()
    (无参数父构造函数)的隐式调用作为第一条语句。实际上,有一个隐式super()调用。它是n