当前位置: 首页 > 面试题库 >

静态初始化程序在构造函数之后运行,为什么?

暨鹭洋
2023-03-14
问题内容

我有2节课:

Class A:

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

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

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

Class B:

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

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

I create a Main class which just creates new A:

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

The output I get is:

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

如您所见,A的构造函数在其静态初始值设定项之前被调用。

我了解它与我创建的循环依赖关系有关,但我印象中静态初始化程序应始终在构造函数之前运行。

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

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


问题答案:

static B b = new B();

is before

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

因此,您需要在打印之前初始化B实例”A static block”。

初始化B类意味着您需要创建一个A实例。因此,

构造A实例之前,无法打印“静态块” 。

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

Note the warning in the
specification
:

因为Java编程语言是多线程的,所以
类或接口的初始化需要仔细的同步,因为某些其他线程
可能试图同时初始化同一类或接口。

可能会递归地请求类或接口的初始化,作为该类或接口的初始化的一部分
;例如,类A中的变量初始值设定项可能会调用
不相关的类B的方法,而后者又可能会调用类
A的方法。Java虚拟机的实现负责
通过使用同步来实现同步和递归初始化。
遵循以下步骤[文档继续执行完整步骤]

与其他语言一样,使用Java的最佳实践基本上是避免循环依赖,因为它们的分辨率可能很难预测。



 类似资料:
  • 我有2个班: A类: B类: 我创建了一个主类,它只创建了一个新的: 我得到的输出是: 如您所见,在静态初始值设定项之前调用了的构造函数。 我知道这与我创建的循环依赖有关,但我的印象是静态初始化器应该总是在构造函数之前运行。 发生这种情况的原因是什么(技术上在java实现中)? 是否建议一起避免静态初始化器?

  • 问题内容: Python中是否有诸如静态构造函数之类的东西? 如何在Python中实现静态构造函数? 这是我的代码…当我这样调用App时不会触发。该不是静态构造函数或静态初始化。 我必须这样称呼它,它每次都会实例化App类: 这是我的课: 每次调用的问题是重新创建了App对象。我的“真实” App类很长。 问题答案: 提示:任何引用都将需要实例化该类。您可以这样做: 但是,来吧,这似乎有很多不足。

  • 假设你有这个代码片段 例如,如果编译器决定让它看起来像 这将是一个问题,因为calculateWaitTime()生成一个新线程,该线程可能会将集合视为null或其中没有1。 那么问题又来了,这种重新排序可能吗?或者所有在构造函数之外初始化的最终字段都是在构造函数之前初始化的,或者至少总是由编译器移动到构造函数的顶部

  • 问题内容: 表示变量只能在构造函数中分配一次。 表示它是一个类实例。 我不明白为什么禁止这样做。这些关键字在哪里互相干扰? 问题答案: 每次创建该类的实例时,都会调用一个构造函数。因此,上述代码意味着x的值将在每次创建实例时重新初始化。但是由于变量被声明为final(和static),因此您只能这样做 但是,如果删除静态,则可以执行以下操作: 或这个:

  • 问题内容: 假设我有 什么时候初始化?之前,之后,取决于? 如果我有一个与的全局定义冲突的构造函数,例如在上面的第三个构造函数中,该怎么办?取哪个值? 这不会给我造成任何问题,但我只是想更好地理解该语言。我喜欢了解这些小知识,以便以后可以潜在地利用它们。 问题答案: 变量被初始化为其类型的默认值(0,null等) 首先,调用超类构造函数。如果超类构造函数调用任何在该类中重写的虚拟方法,则该重写将看