Betrachten Sie den folgenden Code ein:Ist die statische Initialisierung von nicht endgültigen statischen Feldern sicher?
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();
...
}
}
Kann die Linie, die eine NullPointerException
in einer gleichzeitigen Situation encoderFactory
in encode()
jemals werfen greift?
Ja, ich bin mir bewusst, dass in diesem Fall encoderFactory
leicht als endgültig erklärt werden könnte, was diese Frage etwas strittig machen wird.
Allerdings ist mein Interesse hier, ob der Code wie oben beschrieben immer noch sicher veröffentlicht encoderFactory
. Wenn ich die JLS 12.4 verstehe, sollte das der Fall sein. Die Schritte der statischen Initialisierung scheinen keine Möglichkeit zuzulassen, dass ein Thread statische Felder in ihrem nicht initialisierten Zustand (d. H. Kein Vorfall) sieht, sobald er die Klasse als initialisiert ansieht. Ich dachte, dass die JLS klarstellt, dass statische Initialisierung eine Speicherbarriere bildet.
Anscheinend wurde eine solche NullPointerException
beobachtet, und wir haben es behoben, indem wir dieses Feld endgültig gemacht haben. Während es sicherlich eine gute Sache ist, bin ich immer noch verwirrt, wie man einen Null-Zeiger mit diesem Muster sehen kann, ansonsten ist ein viel größeres Problem im Gange, da es bedeuten könnte, dass jede anfängliche Zuweisung von nicht endgültigen statischen Feldern möglicherweise nicht möglich ist sei sichtbar.
Wenn die Annahme, dass die statische Initialisierung eine Speicherbarriere bietet, eine zuverlässige ist (was ich glaube), würde das wohl auf einen JDK-Fehler hinweisen? Können Sie sich einen anderen Grund vorstellen als einen JDK-Fehler?
Danke. Das ist auch meine Lektüre, und das habe ich immer geglaubt. Es scheint jedoch, dass für diesen Codetyp eine 'NullPointerException' gesehen wurde. Ich nehme an, das würde dann unbedingt auf einen JDK-Bug hinweisen? Können Sie sich einen anderen Grund vorstellen als einen JDK-Fehler? – sjlee
@sjlee Bitte bearbeiten Sie den StackTrace in Ihre Frage –