In Java sind Init-Blöcke (Initialisierungsblöcke) spezielle Codeblöcke, die beim Erstellen eines Objektinstanz der Klasse ausgeführt werden, aber vor dem Aufruf des Konstruktors. Es gibt zwei Arten:
public class Beispiel { static { System.out.println("Statischer Block"); } { System.out.println("Instanzblock"); } public Beispiel() { System.out.println("Konstruktor"); } }
Bei der Erstellung eines neuen Objekts wird ausgegeben:
Statischer Block
Instanzblock
Konstruktor
Die Verwendung von Init-Blöcken ist sinnvoll, wenn eine allgemeine Logik für alle Konstruktoren erforderlich ist oder eine komplexe Initialisierung notwendig ist, die nicht in der Variablendeklaration untergebracht werden kann. Aber meistens wird dem Konstruktor der Vorzug gegeben.
Frage: In welcher Reihenfolge werden Felder, statische Blöcke, Instanzblöcke und Konstruktoren bei der Erstellung eines Objekts initialisiert?
Antwort:
Geschichte
In einem großen Projekt gab es ein Problem mit der Initialisierung: Einer der Entwickler verschob die allgemeine Logik vom Konstruktor in den Init-Block, ohne die Reihenfolge der Aufrufe zu beachten. Infolgedessen wurden einige Felder nicht korrekt initialisiert, bevor die Logik gestartet wurde, was zu einem NullPointerException beim Erstellen des Objekts führte.
Geschichte
Die Wiederverwendung eines großen Init-Blocks in einer abstrakten Klasse, von der andere Klassen abgeleitet wurden, führte dazu, dass die Unterklassen die Reihenfolge der Initialisierung nicht ordnungsgemäß überschrieben. Dies verursachte unerwartetes Verhalten beim Vererben und Bugs in Bezug auf die Reihenfolge der Aufrufe von Init-Blöcken und Konstruktoren.
Geschichte
Ein Entwickler nahm an, dass statische Felder bei jeder neuen Erstellung eines Objekts neu initialisiert werden könnten, und fügte im statischen Block eine Logik zur Bereinigung von Ressourcen hinzu. Dies führte dazu, dass Ressourcen nur einmal bei der Klassenladung bereinigt wurden und das gesamte anschließende Gedächtnismanagement "ausfiel". Da der statische Block nur einmal aufgerufen wird, führte dies zu Speicherlecks und fehlerhaftem Ressourcenmanagement.