当前位置: 首页 > 知识库问答 >
问题:

静态初始值设定项在构造函数之后运行,为什么?

燕照
2023-03-14

我有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

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

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

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

是否建议一起避免静态初始化器?

共有1个答案

巴博耘
2023-03-14
static B b = new B();

是以前

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

因此,在打印“静态块”之前,需要初始化B实例。

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

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

请注意规范中的警告:

因为Javahtml" target="_blank">编程语言是多线程的,类或接口的初始化需要仔细的同步,因为其他一些线程可能试图同时初始化相同的类或接口。还有一种可能性是,类或接口的初始化可能会作为类或接口初始化的一部分被递归请求;例如,类A中的变量初始化器可能会调用一个不相关的类B的方法,而B又可能会调用类A的方法。Java虚拟机的实现负责通过使用以下过程来处理同步和递归初始化[doc继续完整的过程]

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

 类似资料:
  • 问题内容: 我有2节课: Class A: Class B: I create a Main class which just creates new A: The output I get is: 如您所见,A的构造函数在其静态初始值设定项之前被调用。 我了解它与我创建的循环依赖关系有关,但我印象中静态初始化程序应始终在构造函数之前运行。 发生这种情况的原因是什么(技术上在Java实现中)? 是

  • 我通过解决一些黑客等级问题来学习java。下面的代码是关于学习静态初始值设定项块的。例外情况是thown和Capture,但程序仍在运行,我不确定原因。 输入:-1,2 预期输出:java.lang.例外:宽度和高度必须为正 实际输出:宽度和高度必须为正-2

  • 问题内容: 只是想知道编译这样的代码的原因: 此代码与构造函数中的代码有什么区别?此代码 在 创建对象 之前 执行。 问题答案: 花括号内没有名称的代码将成为类构造函数的一部分,并在类构造函数所包含的逻辑之前执行。 快速示例:

  • 我相信现代C初始值设定项列表对于初始化对象非常有用,甚至不需要定义自己的构造函数: 但是,当我的类从另一个类继承时,这不起作用: 我尝试添加

  • 所以我正在学习构造函数初始值设定项列表,我写了以下代码: 为此我使用了g编译器。它调用的是构造函数而不是复制构造函数。它应该调用复制构造函数,因为我正在创建一个对象来创建另一个对象?这里的问题是什么,标准对此怎么说?

  • 我有以下代码: 我希望输出是:“base constructor,test:50”,但事实并非如此,因为构造函数是在初始化之前调用的,没有错误或警告,它只是编译。 有什么方法可以让构造函数在之后被调用吗?或者这是总体上的糟糕设计? 我正在尝试将所有的init方法和它们的调用放入构造函数insted中,这个行为阻止了我这样做。