面对构造函数静态块和代码块的执行顺序问题

Facing Problem with order of execution of constructor static block and code block

我知道当我创建实例静态块时,首先初始化代码块,然后在此处构造我的代码

public class Main{

public Main() {
    out.println("constructor initialised");
}

static {
    out.println("static block initialised");
}
{
    out.println("Code block initialised");
}

public static void main(String... args) {

    new Main();
}

}

这样输出

静态块已初始化
代码块已初始化
构造函数初始化

上面的输出清楚了我的概念,但是当我像这样扩展一些 class 时

public class Main extends Bear{

public Main() {
    out.println("constructor initialised");
}

static {
    out.println("static block initialised");
}
{
    out.println("Code block initialised");
}

public static void main(String... args) {
    new Main();
}
}

熊Class

class Bear{
static {
    out.println("static block initialised of bear class");
}

{
    System.out.println("Code bLock initialised of bear class");
}

void run() {
    out.println("running...");
}
}

输出如下:

bear 初始化的静态块class
静态块已初始化
bear 的代码块初始化 class
代码块已初始化
构造函数初始化

当扩展 class 时,执行顺序发生了变化 我不明白为什么会发生上面的输出

我相信这些工作的方式是:

  • 静态块在 class 首次加载时调用(基本上是您第一次在项目中使用 class ),因此这些首先发生
  • 初始化的(代码)块在开始时(在调用 super() 之后)基本上被复制到每个构造函数中,因此您可以共享代码(虽然不是很好的风格)
  • 构造函数很好...构造函数...

它们按此顺序出现的原因是子 class 依赖于父 class 的存在。 child class 不能先于parent 加载,所以调用parent 的static initializer 加载它,然后再加载child class。

每个 class 加载后,它将调用构造函数(包括非静态代码块)来初始化您的对象。同样,子 class 依赖于存在并正确设置的父级,因此首先调用基础 class 构造函数,然后调用派生的 class 构造函数。需要按此顺序完成,以便子 class 可以依赖于父的某些参数。如果您将显式构造函数添加到基 class,您将获得如下所示的输出:

Class 已加载

  • bear 初始化的静态块class
  • 静态块已初始化

基础class构造函数

  • 熊的代码块初始化class
  • bear 的构造函数初始化 class

子class构造函数

  • 代码块已初始化
  • 构造函数初始化

如果您两次调用 new Main(),您会在第一次看到上面的输出,但第二次可能会丢失静态块,因为 class 已经加载。