Есть ли какие-либо гарантии в JLS о порядке выполнения статических блоков инициализации? - PullRequest
2 голосов
/ 12 июня 2010

Интересно, надежно ли использовать такую ​​конструкцию, как:

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 инициализацию в конце верхнего блока init. Просто вопрос вкуса; я сделаю это, если описанная конструкция ненадежна)

1 Ответ

7 голосов
/ 12 июня 2010

Да, блоки статического инициализатора гарантированно выполняются в текстовом порядке.

Из JLS, раздел 12.4.1 :

Намерение состоит в том, чтокласс или тип интерфейса имеет набор инициализаторов, которые переводят его в согласованное состояние, и что это состояние является первым состоянием, которое наблюдается другими классами. Статические инициализаторы и инициализаторы переменных класса выполняются в текстовом порядке и могут не ссылаться на переменные класса, объявленные в классе, объявления которых появляются текстуально после использования, даже если эти переменные класса находятся в области видимости (§8.3.3).Это ограничение предназначено для обнаружения во время компиляции большинства циклических или иным образом искаженных инициализаций.

И из 12.4.2 :

Далее,выполнить либо инициализаторы переменных класса и статические инициализаторы класса, либо инициализаторы полей интерфейса, в текстовом порядке , как если бы они были единым блоком.

Хотя личноЯ бы поместил все объявления переменных в начале, а затем один статический блок инициализатора.Я считаю, что за этим намного легче следовать.

...