Java - 此代码中的初始化顺序是什么?

标签 java oop

<分区>

在下面的Java代码中,Beetle类继承了Insect类。

class Insect {

    private int i = 9;
    protected int j;

    Insect() {
        System.out.println("i = " + i + ", j = " + j);
        j = 39;
    }
    private static int x1
            = printInit("static Insect.x1 initialized");

    static int printInit(String s) {

        System.out.println(s);
        return 47;
    }
}

public class Beetle extends Insect {

    private int k = printInit("Beetle.k initialized");

    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }
    private static int x2
            = printInit("static Beetle.x2 initialized");

    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

输出有点令人困惑。

static Insect.x1 initialized

static Beetle.x2 initialized

Beetle constructor

i = 9, j = 0

Beetle.k initialized

k = 47 j = 39

这个特定示例中的初始化顺序是什么?

为什么 x2 在 x1 之后立即初始化?以及为什么main方法的第一行(System.out.println("Beetle constructor");)在x1和x2初始化之后执行。好困惑。

我知道派生类构造函数会自动调用基类构造函数(除非它有参数并且您会使用 super 关键字)。我知道变量在构造函数之前初始化,而静态变量在其他变量之前初始化。

最佳答案

x1x2 是静态的。这意味着它们在加载类时被初始化。由于 main 方法在 Beetle 中,因此必须在调用 main 之前加载该类。这就是为什么 x1x2 初始化是您首先看到的原因。不确定为什么这两者的顺序是这样。

现在您正在调用 main 并执行 System.out.println("Beetle constructor");。然后它调用 Beetle(),它首先隐式调用 super()(又名 Insect())。这会打印 i = 9, j = 0 因为 i 是 9 而 j 在那个时候还没有被初始化,这意味着它有默认值整数值 0。

现在 j 设置为 39,流程在 Beetle() 中继续。这现在初始化了 Beetle 的字段,在您的例子中是 k。所以当涉及到Beetle()中的显式代码时, super 构造函数将k初始化为47,将j初始化为39。

关于Java - 此代码中的初始化顺序是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38748352/

相关文章:

Java 商店注册应用程序导航机制

C++类——如何从另一个成员函数引用一个成员函数

javascript - 发送整个对象只是为了更新状态?

java 正确理解 OOP 概念

java - 从另一个类访问公共(public)变量?

java - Spring MVC : Spring Security 4 doesn't intercept

java - PKIXCertPathBuilder 使用 Bouncy CaSTLe 提供程序失败但使用默认 (SUN) 提供程序

java - 是否可以为整个应用程序设置自定义字体?

c# - 在这种情况下我应该使用接口(interface)还是抽象类?

java - 使用抽象类中的重写方法 (Java)