静态初始化构造函数运行后,为什么呢?(Static initializer runs after t

2019-07-05 20:02发布

我有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");
     }
}

我创建了刚刚创造了新的一个主类:

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实现)的原因是什么?

它是建议,以避免静态初始化所有在一起吗?

Answer 1:

static B b = new B();

是前

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

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

和初始化B级意味着你需要创建一个一个实例。 因此,有构成在A实例之前,要打印没有办法为“静态块”。

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

请注意,在报警的规格 :

因为Java编程语言是多线程的,一类或接口的初始化阶段需要仔细同步,因为一些其他线程试图在同一时间进行初始化同一类或接口。 还存在一个类或接口的初始化可被递归地请求作为类或接口的初始化的一部分的可能性; 例如,在类A的变量初始化可能调用一个不相关的类B的一个方法,这可能会反过来调用类A的方法的Java虚拟机的实现是负责通过使用照顾同步和递归初始化的下面的过程[商务部继续与完整的程序]

最好的做法,在Java在其他语言中,基本上是为了避免循环依赖它们的分辨率可能很难预测。



文章来源: Static initializer runs after the constructor, why?