ProgrammierungMiddle/Senior Java Entwickler

Was ist die Klasseninitialisierungsreihenfolge in Java, wie funktioniert sie und welche Folgen kann ein falsches Verständnis der Reihenfolge der Initialisierung von statischen und nicht-statischen Mitgliedern haben?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Die Klasseninitialisierungsreihenfolge in Java (class initialization order) bestimmt, in welcher Reihenfolge Felder, Blöcke und Konstruktoren initialisiert werden. Kurz gesagt:

  1. Statische Felder und statische Initialisierer werden in der Reihenfolge ihrer Erscheinung in der Klasse ausgeführt, wenn die Klasse von der JVM geladen wird (einmal pro Klasse).
  2. Nicht-statische Felder und Initialisierer werden in der Reihenfolge ihrer Erscheinung JEDES MAL bei der Erstellung einer Instanz ausgeführt, bevor der Konstruktor aufgerufen wird.
  3. Konstruktor wird nach der Initialisierung aller Felder und Blöcke ausgeführt.

Beispiel

class Parent { static { System.out.println("Parent static"); } { System.out.println("Parent init"); } Parent() { System.out.println("Parent constructor"); } } class Child extends Parent { static { System.out.println("Child static"); } { System.out.println("Child init"); } Child() { System.out.println("Child constructor"); } } // new Child() -> welche Reihenfolge?

Die Ausgabe wird sein:

  1. Parent static
  2. Child static
  3. Parent init
  4. Parent constructor
  5. Child init
  6. Child constructor

Zuerst die statischen Blöcke der Eltern, dann die statischen Blöcke der Kinder, dann die nicht-statischen Blöcke und Konstruktoren in der Reihenfolge der Vererbung.

Fangfrage.

Frage: Wann genau werden die statischen Initialisierer in der Klasse ausgeführt:

class Ex {
    static { System.out.println("static"); }
}

— bei der Erstellung der ersten Instanz oder bei der ersten Verwendung eines statischen Methoden/Felds?

Antwort: Der statische Initialisierer wird bei der ersten Zugriffs auf die Klasse ausgeführt, einschließlich des Zugriffs auf jedes statische Mitglied (Methode/Feld), und nicht nur bei der Erstellung einer Instanz.

Beispiele für reale Fehler aufgrund von Unkenntnis der Feinheiten des Themas.


Geschichte

In einer Bankenapplikation wurde statischer Verbindungs-Pool im statischen Block initialisiert, aber aufgrund des Zugriffs auf eine statische Methode vor der Erstellung der ersten Instanz war noch keine Verbindung erstellt worden. Das führte zu NullPointerException unter Last.


Geschichte

Der Logging-Service hing von einem nicht-statischen Feld ab, das nach dem Aufruf des Konstruktors der Elternklasse initialisiert wurde. Protokolle wurden in den null-Logger geschrieben, und wichtige Fehlermeldungen gingen verloren.


Geschichte

Als ein neues Feld mit einem Standardwert hinzugefügt wurde, platzierte der Entwickler es nach dem Initialisierungsblock: der Block versuchte, auf ein noch nicht initialisiertes Feld zuzugreifen, was während des Starts der Anwendung zu Fehlern und einer schwierigen Fehlersuche führte.