【问题标题】:Which constructor is invoked [duplicate]调用哪个构造函数[重复]
【发布时间】:2019-05-14 09:59:59
【问题描述】:

假设以下代码。我不明白为什么输出是 B的构造函数被调用 A 的构造函数被调用。

我以为输出只是“调用了 A 的构造函数”,因为构造 A(int t) 不调用构造函数 B?

public class Test {
    public static void main(String[] args) {
        A a = new A(3);
    }
}

class A extends B {
    public A(int t) {
        System.out.println("A's constructor is invoked");
    }
}

class B {
    public B() {
        System.out.println("B's constructor is invoked");
    }
}

【问题讨论】:

  • 无代码 -> 没有调用构造函数
  • 什么代码?它在哪里? minimal reproducible example
  • @Anna 构造函数所做的第一件事就是调用它的父类的构造函数,无论您是否专门对其进行编码。与专门调用父类构造函数的唯一区别是可以选择调用父类的哪个构造函数
  • @AnnaSaabel 阻止 A 的构造函数调用 B 的构造函数的唯一方法是不允许 A 扩展 B
  • @Anna Saabel 始终记住构造函数的第一行将调用其超类构造函数,即使您不保留它,编译器也会将其保留在 .class 文件中。如果您显式保留一个,那么编译器将调用另一个,默认情况下它将调用无参数构造函数。

标签: java oop constructor


【解决方案1】:

每当调用派生类的默认构造函数时,都会自动调用基类的默认构造函数,并且参数化构造函数遵循相同的规则。这就是您获得输出的原因: B 的构造函数被调用。 调用了 A 的构造函数。

【讨论】:

    【解决方案2】:

    super() 由编译器自动添加到每个类的构造函数中。

    默认构造函数由编译器自动提供,但它也为第一条语句添加了 super(),如图所示。所以先调用base的构造函数。

    Refer to below picture to understand it.

    【讨论】:

    • "默认构造函数由编译器自动提供",不,不是。
    • 我在很多网站上都读过它。请提供正确的资源来理解它。 @Stultuske [javawithus.com/tutorial/…
    • 提供死链接不会赢得争论。编译器将添加一个默认构造函数,如果且仅当不存在另一个构造函数时。因此,在 OP 的代码中,编译器不会提供任何默认构造函数。 B 类已经包含一个,A 类包含一个参数化的构造函数
    • 刚刚转到该链接(您的错误是您在 url 中添加了结束 ])。消息来源不可靠。作者假设所有最终变量都是常量,而在很多(如果不是大多数)情况下,情况并非如此。
    • 知道了。谢谢你。 :)
    【解决方案3】:

    如果您没有在子类构造函数中调用任何超类构造函数,则默认(无参数)构造函数调用将被隐式添加为子类构造函数中的第一条语句:

    class A extends B {
        public A(int t) {
            super(); // Added by compiler
            System.out.println("A's constructor is invoked");
        }
    }
    

    如果超类没有无参数构造函数(无论是显式定义的还是隐式定义的),您将收到编译器错误,这意味着您必须在第一条语句中显式调用现有的超类构造函数在您的子类构造函数中。

    隐式超级构造函数 B() 未定义。必须显式调用另一个构造函数

    如果类没有显式定义的构造函数,则编译器会将隐式无参数构造函数添加到类中。

    【讨论】:

      猜你喜欢
      • 2015-07-02
      • 2013-06-12
      • 1970-01-01
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多