【问题标题】:A question on Java constructor and class member initialization [duplicate]关于Java构造函数和类成员初始化的问题[重复]
【发布时间】:2020-07-15 07:23:52
【问题描述】:

我试图理解为什么以下 Java 代码的输出是这样的:

class A {
    public A() {
        System.out.print("A()");
    }
    public static void main(String[] args) {

    }
}
class B {
    public B() {
        System.out.print("B()");
    }

    public static void main(String[] args) {}
}
class C extends A {
    B b = new B();
}

public class E05SimpleInheritance {
    public static void main(String args[]) {
        new C();
    }
}

输出:

"A()B()"

我想当E05SimpleInheritance公共类的main方法被调用时应该会发生以下事情

  1. 加载非公共类 C 并初始化其字段(在调用类 C 的默认构造函数之前)
  2. 由于其成员“b”是 B 类的对象,因此 B 类被加载到内存中
  3. 由于我们构造了一个 B 类对象,它的构造函数被调用,它应该打印 B()
  4. 调用 C 的默认构造函数,它会自动调用打印 A() 的超类 A 的构造函数

所以最终输出应该是 B()A() 这显然是错误的,所以我真的不明白在这种情况下代码是如何流动的。你能告诉我为什么打印的是 A()B() 而不是 B()A()

【问题讨论】:

标签: java constructor


【解决方案1】:

您的错误在于步骤 1:

加载非公共类C并初始化其字段(在调用C类的默认构造函数之前)

不是正在发生的事情。实际上,非静态字段在构造函数的开头处被初始化,而不是在之前。并且基类构造函数被隐式(或显式)调用,甚至在之前

换句话说,javacC 生成代码,相当于以下代码:

class C extends A {
    B b;

    C() {
        super();
        b = new B();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多