は、次のコードを考えてみましょう:非最終静的フィールドの静的初期化は安全ですか?
public class Text {
private static ThreadLocal<CharsetEncoder> encoderFactory =
new ThreadLocal<CharsetEncoder>() {
@Override
protected CharsetEncoder initialValue() {
return Charset.forName("UTF-8").newEncoder().
onMalformedInput(CodingErrorAction.REPORT).
onUnmappableCharacter(CodingErrorAction.REPORT);
}
};
public static ByteBuffer encode(String string, boolean replace)
throws CharacterCodingException {
CharsetEncoder encoder = encoderFactory.get();
...
}
}
encode()
でencoderFactory
をアクセスラインは、これまでの同時状況でNullPointerException
を投げることはできますか?
はい、このケースでは、encoderFactory
は最終的には簡単に宣言でき、この質問はやや疑問に思うことをよく認識しています。
ただし、私の興味はここでも上記のコードが安全にencoderFactory
を発行するかどうかです。もし私がJLS 12.4を理解していれば、そうでなければなりません。静的初期化のステップは、初期化されたクラスを見た後に、どのスレッドも初期化されていない状態(つまり、何も起こりません)で静的フィールドを見る可能性を残さないようです。私はJLSが静的初期化がメモリの壁を形成することを合理的に明らかにしたと思った。
明らかにこのようなNullPointerException
が観察されましたが、このフィールドを最終的に修正することで終了しました。それは確かに良いことですが、私はまだこのパターンでヌルポインタを見る方法を困惑しています。そうでなければ、より大きな問題が起こります。最終的でない静的フィールドの初期割り当ては、見えるようにする。
静的初期化がメモリバリアを提供するという前提が信頼できるもの(私はそれが信じている)だとすれば、必ずJDKのバグを指摘するでしょうか? JDKのバグ以外の理由が考えられますか?
ありがとうございました。それは私の読書でもあり、私はいつもその通りだと考えました。しかし、そのタイプのコードでは 'NullPointerException'が見られました。私は、JDKのバグを必ず指摘するでしょうか? JDKのバグ以外の理由が考えられますか? – sjlee
@sjlee質問にスタックトレースを編集してください –