构造函数调用必须是构造函数中的第一条语句。

7

我不理解为什么在构造函数中将 this(1); 移到最后一行时,下面的代码会显示错误信息 Constructor call must be the first statement in a constructor

package learn.basic.corejava;

public class A {
    int x,y;

    A()
    {     
        // this(1);// ->> works fine if written here
        System.out.println("1");
        this(1);  //Error: Constructor call must be the first statement in a constructor
    }

    A(int a)
    {
        System.out.println("2");
    }

    public static void main(String[] args) { 
        A obj1=new A(2);  
    }   
}

我在StackOverflow上检查了很多关于这个话题的答案,但我仍然无法理解其中的原因。请用一些简单的例子和解释帮助我澄清这个错误。


原因是“构造函数调用必须是构造函数中的第一条语句”。因此,在构造函数内部,对this(...)的调用必须是第一条指令。如果它在System.out.println("1")之后出现,则不是第一条指令,而是第二条指令。 - JB Nizet
@OldProgrammer,我已经看过那些答案,但仍然无法理解,所以我在这里再次问。再问一遍是否违法? - beginner
因为这是语言开发者设计的方式。这也是有道理的。这确保了在执行派生类构造函数中的任何其他语句之前,父类的任何属性/行为都处于适当的状态。 - OldProgrammer
除非新问题有显著不同,否则您不应再次提出相同的问题。 - Kevin Panko
2个回答

11

正如您所知,这个可以工作:

A() {
      this(1);
      System.out.println("1");
}

为什么?因为这是语言规则,包含在Java语言规范中:在同一个类中调用另一个构造函数(使用this(...)部分)或调用父类的构造函数(使用super(...)),必须放在第一行。这是一种确保在初始化当前对象之前初始化父级状态的方法。
要了解更多信息,请查看这个帖子,它详细解释了这种情况。

2
是的,我知道这是规则。但我想知道为什么如果我把它写在最后面就无效了?我必须知道这个,因为在印度的面试中,我的面试官会问这样的问题。 - beginner
1
正如我之前所说:如果你将this()的调用留在最后,那么你就有可能在上面的行中引用尚未初始化的超类状态。虽然在所示代码中并没有发生这种情况,但在一般情况下编译器无法确定,因此不允许这样做。 - Óscar López
1
@rani 有什么困惑吗?他回答了你的问题。语言规范如此描述,那么它就一定是这样。 - ach
好的,我的理解是“这是Java语言的一项规则,并且它还说'在初始化当前对象之前应先初始化其父状态'”。如果面试官问到这样的问题,我这个理解是否足够向他解释呢? - beginner
@rani 如果你真正理解了这些概念,你就能自己找出答案。 - ach

1
错误告诉你问题所在。
A()
{     
      System.out.println("1");
      this(1);  //Error: Constructor call must be the first statement in a constructor
}

即,您必须首先调用构造函数。
A()
{
      this(1);
      System.out.println("1");
}

这同样适用于对super的调用

class B extends A
{
    B()
    {
        super();
        System.out.println("1");
    }
}

原因在这里得到了解答:here


谢谢你的回答。我看了这些(https://dev59.com/uXM_5IYBdhLWcg3w6X1e)的答案,但仍然无法理解,所以我在这里问这个问题。 - beginner

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