Java静态初始化顺序 [英] Java Static Initialization Order

查看:157
本文介绍了Java静态初始化顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试发现初始化发生的顺序,或者说是为什么初始化按此顺序发生的原因。鉴于代码:

I'm trying to discover the order in which initialization occurs, or rather the reason behind why initialization occurs in this order. Given the code:

public class Main {

    {
        System.out.printf("NON-STATIC BLOCK\n");
    }

    static{
        System.out.printf("STATIC BLOCK\n");
    }

    public static Main m = new Main();

    public Main(){
        System.out.printf("MAIN CONSTRUCTOR\n");
    }

    public static void main(String... args) {
        //Main m = new Main();
        System.out.printf("MAIN METHOD\n");

    }
}

输出:

STATIC BLOCK

NON-STATIC BLOCK

MAIN CONSTRUCTOR

MAIN METHOD

然而,移动 m '初始化块之前的声明产生:

However, moving m's declaration before the initialization block produces:

NON-STATIC BLOCK

MAIN CONSTRUCTOR

STATIC BLOCK

MAIN METHOD

我绝对没有想法为什么它按此顺序发生。此外,如果我在 m 的声明中消除 static 关键字,则init块和构造函数都不会触发。任何人都可以帮我解决这个问题吗?

and I have absolutely no idea why it occurs in this order. Furthermore, if I eliminate the static keyword in the declaration of m, neither the init block nor the constructor fire. Can anyone help me out with this?

推荐答案

我认为你只是缺少 JLS的第12.4.2节,其中包括:

I think you're just missing section 12.4.2 of the JLS, which includes:


接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项,或接口的字段初始值设定项,就好像它们一样是一个单独的块。

Next, execute either the class variable initializers and static initializers of the class, or the field initializers of the interface, in textual order, as though they were a single block.

文本顺序部分是重要的一部分。

The "in textual order" part is the important bit.

如果将 m 从静态变量更改为实例变量,则 class 初始化不会初始化该字段 - 它只能由实例初始化初始化(即构建实例时)。目前,这会导致堆栈溢出 - 创建一个实例需要创建另一个实例,这需要创建另一个实例,等等。

If you change m from being static variable to an instance variable, then the field won't be initialized by class initialization - it'll only be initialized by instance initialization (i.e. when an instance is constructed). At the moment, that'll cause a stack overflow - creating one instance requires creating another instance, which requires creating another instance, etc.

编辑:类似 12.5节指定实例初始化,包括这些步骤:

Similarly section 12.5 specifies instance initialization, including these steps:



  • 为此类执行实例初始值设定项和实例变量初始值设定项,分配实例的值变量初始化器到相应的实例变量,按从左到右的顺序,它们以文本方式出现在类的源代码中。如果执行任何这些初始值设定项导致异常,则不会处理其他初始值设定项,并且此过程会突然完成同样的异常。否则,继续执行步骤5.

  • Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. If execution of any of these initializers results in an exception, then no further initializers are processed and this procedure completes abruptly with that same exception. Otherwise, continue with step 5.

执行此构造函数的其余部分。如果该执行突然完成,则由于同样的原因,此过程突然完成。否则,此过程正常完成。

Execute the rest of the body of this constructor. If that execution completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, this procedure completes normally.

这就是为什么你会看到 主要构造函数之前的非静态区块。

So that's why you're seeing "NON-STATIC BLOCK" before "MAIN CONSTRUCTOR".

这篇关于Java静态初始化顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆