JLS中是否有关于执行静态初始化块的顺序的保证? [英] Are there any guarantees in JLS about order of execution static initialization blocks?

查看:117
本文介绍了JLS中是否有关于执行静态初始化块的顺序的保证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道使用如下构造是否可靠:

  private static final Map< String,String> engMessages; 
private static final Map< String,String> rusMessages;

static {
engMessages = new HashMap< String,String> (){{
put(msgname,value);
}};
rusMessages = new HashMap< String,String> (){{
put(msgname,значение);
}};
}

private static Map< String,String> msgSource;

static {
msgSource = engMessages;
}

public static String msg(String msgName){
return msgSource.get(msgName);
}

我是否有可能获得 NullPointerException 因为 msgSource 初始化块将在初始化 engMessages

(关于为什么我不做 msgSource 初始化结束时的初始化。块:只是品味问题;如果描述的构造不可靠,我会这样做。)

解决方案

是的,保证静态初始化程序块按文本顺序执行。



来自JLS,第12.4.1节


意图是一个班级或者接口类型有一组初始值设定项,使它处于一致状态,并且该状态是其他类观察到的第一个状态。 静态初始值设定项和类变量初始值设定项以文本顺序执行,并且可能不会引用在声明在使用后以文本方式出现的类中声明的类变量,即使这些类变量在范围内(§8.3) 0.3)。此限制旨在在编译时检测大多数循环或其他格式错误的初始化。


并且来自 12.4.2


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


就个人而言,我会把所有变量声明放在开头,然后是单个静态初始化块。我认为要更容易理解。


I wonder if it's reliable to use a construction like:

private static final Map<String, String> engMessages;
private static final Map<String, String> rusMessages;

static {
    engMessages = new HashMap<String, String> () {{
        put ("msgname", "value");
    }};
    rusMessages = new HashMap<String, String> () {{
        put ("msgname", "значение");
    }};
}

private static Map<String, String> msgSource;

static {
    msgSource = engMessages;
}

public static String msg (String msgName) {
    return msgSource.get (msgName);
}

Is there a possibility that I'll get NullPointerException because msgSource initialization block will be executed before the block which initializes engMessages?

(about why don't I do msgSource initialization at the end of upper init. block: just the matter of taste; I'll do so if the described construction is unreliable)

解决方案

Yes, static initializer blocks are guaranteed to execute in textual order.

From the JLS, section 12.4.1:

The intent is that a class or interface type has a set of initializers that put it in a consistent state, and that this state is the first state that is observed by other classes. The static initializers and class variable initializers are executed in textual order, and may not refer to class variables declared in the class whose declarations appear textually after the use, even though these class variables are in scope (§8.3.3). This restriction is designed to detect, at compile time, most circular or otherwise malformed initializations.

And from 12.4.2:

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.

Personally though, I'd put all the variable declarations at the start, and then a single static initializer block. I consider that to be a lot easier to follow.

这篇关于JLS中是否有关于执行静态初始化块的顺序的保证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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