2

次のような構造を使用するのは信頼できるのだろうか。

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ため、取得する可能性はありますか?msgSourceengMessages

msgSource(上部の初期化ブロックの最後で初期化を行わない理由について:好みの問題です。説明されている構造が信頼できない場合は、そうします)

4

1 に答える 1

8

はい、静的初期化ブロックはテキスト順に実行されることが保証されています。

JLSのセクション12.4.1から:

その目的は、クラスまたはインターフェイスタイプに、一貫性のある状態にする一連の初期化子があり、この状態が他のクラスによって監視される最初の状態であるということです。静的初期化子とクラス変数初期化子はテキスト順に実行され、これらのクラス変数がスコープ内にある場合でも、使用後に宣言がテキストで表示されるクラスで宣言されたクラス変数を参照しない場合があります(§8.3.3)。この制限は、コンパイル時に、ほとんどの循環型またはその他の不正な形式の初期化を検出するように設計されています。

そして12.4.2から:

次に、クラスのクラス変数初期化子と静的初期化子、またはインターフェイスのフィールド初期化子のいずれかを、単一のブロックであるかのようにテキスト順に実行します。

個人的には、最初にすべての変数宣言を配置し、次に単一の静的初期化ブロックを配置します。私はそれをフォローするのがはるかに簡単だと思います。

于 2010-06-12T09:53:40.047 に答える