gpt4 book ai didi

java - 静态初始化器在构造函数之后运行,为什么?

转载 作者:IT老高 更新时间:2023-10-28 20:29:13 24 4
gpt4 key购买 nike

我有 2 节课:

A类:

public class A {
static B b = new B();

static {
System.out.println("A static block");
}

public A() {
System.out.println("A constructor");
}
}

B类:

public class B {
static {
System.out.println("B static block");
new A();
}

public B() {
System.out.println("B constructor");
}
}

我创建了一个 Main 类,它只创建了新的 A:

public class Main {
public static void main(String[] args) {
new A();
}
}

我得到的输出是:

B static block
A constructor
B constructor
A static block
A constructor

如您所见,A 的构造函数在其静态初始化程序之前被调用。

我知道这与我创建的循环依赖有关,但我的印象是静态初始化程序应该始终在构造函数之前运行。

发生这种情况的原因是什么(技术上在 java 实现中)?

是否建议同时避免使用静态初始化器?

最佳答案

static B b = new B();

在之前

static {
System.out.println("A static block");
}

所以你需要在打印"A static block"之前初始化B实例。

而初始化 B 类意味着你需要创建一个 A 实例。因此,在构造 A 实例之前无法打印“静态 block ”。

是的,A 的静态初始化在构造函数启动之前启动,但除了死锁之外,您需要的序列没有其他解决方案。

注意 the specification 中的警告:

Because the Java programming language is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time. There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface; for example, a variable initializer in class A might invoke a method of an unrelated class B, which might in turn invoke a method of class A. The implementation of the Java virtual machine is responsible for taking care of synchronization and recursive initialization by using the following procedure [the doc goes on with the complete procedure]

在 Java 和其他语言中的最佳实践基本上是避免循环依赖,因为它们的解决方案可能很难预测。

关于java - 静态初始化器在构造函数之后运行,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13948170/

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