Betrachten Sie diesen Code-Schnipsel:Java: Was passiert mit einem Objekt, dessen Konstruktor fehlgeschlagen ist?
class Test1 {
private static Test1 instance;
@NonNull private final Date date1;
@NonNull private final Date date2;
Test1() throws Exception {
this.date1 = new Date();
Test1.instance = this;
if (true) {
throw new Exception();
}
this.date2 = new Date();
}
public void dump() {
System.out.println("date1: " + date1);
System.out.println("date2: " + date2);
}
static void test() {
Test1 t1 = null;
try {
t1 = new Test1();
} catch (Exception e) {
e.printStackTrace();
}
Test1.instance.dump();
assert t1 == null;
}
}
Test1 Konstruktor wirft immer eine Ausnahme gleich nach mir zu einem statischen Feld zuweisen. Dieses Feld behält einen Verweis auf ein teilweise initialisiertes Objekt: Ein Objekt, das date2
ist, ist null
, obwohl es @NonNull
und final
deklariert ist.
Die Funktion test()
kann nicht direkt eine Referenz auf das generierte t1 erhalten. Nach dem catch
Block ist T1 Null. Und noch, Test1.instance ist nur in Ordnung, und Aufruf seiner dump()
Funktion zeigt, dass date1
ist initialisiert, aber date2
ist null
.
Was geht hier vor? Warum kann ich einen Verweis auf ein Objekt behalten, das sich wirklich in einem unzulässigen Zustand befindet?
EDIT Die Tatsache, dass t1
null ist offensichtlich, ist (im Gegensatz zu In Java what happens when an object fails to be instantiated?). Diese Frage bezieht sich auf den Status des Objekts, das im statischen Feld gespeichert werden konnte.
Das Erstellen und Initialisieren der Instanz sind separate Dinge: Die Instanz wird zuerst erstellt und dann über ihren Konstruktor initialisiert; Selbst wenn das Objekt nicht vollständig initialisiert ist, existiert immer noch eine Instanz. Dies ist ein Beispiel für eine unsichere Veröffentlichung *, die Sie (offensichtlich) vermeiden sollten. –
Mögliches Duplikat von [In Java, was passiert, wenn ein Objekt nicht instanziiert werden kann?] (Http://stackoverflow.com/questions/3421606/in-java-what-happens-when-an-object-fails-to-be -instantiiert) –
@JulienLopez nicht ein Betrogener, bitte siehe bearbeiten. – noamtm