gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 01:58:56 25 4
gpt4 key购买 nike

我知道当我创建一个实例静态 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();
}

}

这样输出

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

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

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 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 类的静态 block 初始化
静态 block 初始化
bear类的代码块初始化
代码块初始化
构造函数初始化

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

最佳答案

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

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

之所以以这样的顺序出现,是因为子类依赖于父类的存在。子类不能在父类之前加载,所以调用父类的静态初始化器加载它,然后再加载子类。

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

类已加载

  • bear 类的静态 block 初始化
  • 初始化静态 block

基类构造函数

  • Bear 类的代码块初始化
  • Bear 类的构造函数初始化

子类构造函数

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

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

关于java - 面对构造函数静态 block 和代码块的执行顺序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68138774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com