【问题标题】:Are there any guarantees in JLS about order of execution static initialization blocks?JLS 中是否有关于执行静态初始化块的顺序的保证?
【发布时间】:2011-03-02 23:25:25
【问题描述】:

我想知道使用这样的结构是否可靠:

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 的块之前执行?

(关于为什么我不在上面的 init.block 末尾做 msgSource 初始化:只是口味问题;如果描述的构造不可靠,我会这样做)

【问题讨论】:

  • 我认为有比这更好的国际化方法。不过,我没有推荐这些方法的专业知识,但我认为这与将源代码之外的字符串外部化(以使非程序员翻译人员更容易工作)和使用各种机制有关已经为国际化而设计,而不是像这样管理自己的地图。
  • @polygenelubricants:部分同意。但我有 3 个原因:1)这对我来说是最简单/最快的方式; 2)这不是一个真正的应用程序,我将其作为我学位工作的一部分; 3) 如果有必要,仍然可以在静态初始化器中解析属性文件(但它不会)。

标签: java static-initialization jls


【解决方案1】:

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

来自 JLS,section 12.4.1

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

来自12.4.2

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

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

【讨论】:

  • 您提供的参考现在已损坏。 this 可以被接受为正确的吗? 静态初始化程序和类变量初始化程序按文本顺序执行,并且不能引用在使用后以文本形式出现的类中声明的类变量,即使这些类变量在范围内(第 8.3.3 节)。
  • @St.Antario:12.4.1 和 12.4.2 都有有用的文本。将把两个链接都放进去。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多