JLS中是否有关于执行静态初始化块的顺序的保证?

时间:2010-06-12 09:51:13

标签: java static-initialization 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初始化。块:只是品味的问题;如果描述的结构不可靠,我会这样做)

1 个答案:

答案 0 :(得分:7)

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

来自JLS,section 12.4.1

  

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

来自12.4.2

  

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

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