Wann erfolgt die statische Initialisierung?

Lesezeit: 4 Minuten

Benutzeravatar von Tony R
Toni R

Wann werden statische Felder initialisiert? Wenn ich nie eine Klasse instanziiere, aber auf ein statisches Feld zugreife, werden ALLE statischen Blöcke und privaten statischen Methoden, die zum Instanziieren privater statischer Felder verwendet werden, zu diesem Zeitpunkt (in der Reihenfolge) aufgerufen?

Was ist, wenn ich eine statische Methode aufrufe? Führt es auch alle statischen Blöcke aus? Vor der Methode?

  • Ähnlich für statische Initialisierungsblöcke: stackoverflow.com/questions/2007666/…

    – Ciro Santilli OurBigBook.com

    23. März 2015 um 9:04 Uhr

Benutzeravatar von Stephen C
Stefan C

Die statische Initialisierung einer Klasse erfolgt normalerweise unmittelbar vor dem ersten Auftreten eines der folgenden Ereignisse:

  • eine Instanz der Klasse wird erstellt,
  • eine statische Methode der Klasse wird aufgerufen,
  • ein statisches Feld der Klasse zugewiesen wird,
  • ein nicht konstantes statisches Feld verwendet wird, oder
  • für eine Top-Level-Klasse wird eine Assert-Anweisung ausgeführt, die lexikalisch innerhalb der Klasse verschachtelt ist1.

Sehen JLS 12.4.1.

Es ist auch möglich, eine Klasse zur Initialisierung zu zwingen (falls sie noch nicht initialisiert wurde), indem Sie verwenden Class.forName(fqn, true, classLoader) oder die Kurzform Class.forName(fqn)


Wann findet die statische Klasseninitialisierung statt?

Siehe oben.

Wann werden statische Felder initialisiert?

Als Teil der statischen Klasseninitialisierung; siehe oben.

Wenn ich nie eine Klasse instanziiere, aber auf ein statisches Feld zugreife, werden ALLE statischen Blöcke und privaten statischen Methoden, die zum Instanziieren privater statischer Felder verwendet werden, zu diesem Zeitpunkt (in der Reihenfolge) aufgerufen?

Ja. (Modulo, dass nichts wirklich augenblicklich ist.)

Was ist, wenn ich eine statische Methode aufrufe? Führt es auch alle statischen Blöcke aus? Vor der Methode?

Ja und ja.


Beachten Sie, dass es möglich ist, Code zu erstellen, in dem Sie die beobachten können standardmäßig initialisiert Wert eines statischen Feldes.


1 – Der letzte Aufzählungspunkt war im JLS für Java 6 bis Java 8 vorhanden, aber es war anscheinend ein Fehler in der Spezifikation. Es wurde schließlich im Java 9 JLS korrigiert: siehe Quelle.

  • Es gibt jedoch einen gemeinsamen Fallstrick. Primitive u Strings werden ersetzt und nicht referenziert. Wenn Sie auf a verweisen class Other { public static final int VAL = 10; } aus irgendeiner Klasse MyClass { private int = Other.VAL; }die Klasse Other wird nicht geladen. Stattdessen ersetzt der Compiler zur Kompilierzeit einfach das letzte Feld.

    – Raffael Winterhalter

    28. Oktober 2013 um 9:45 Uhr


  • @RafaelWinterhalter – ja … das ist der Konstante Statischer Feldfall.

    – Stefan C

    14. Dezember 2015 um 3:03 Uhr

  • @RafaelWinterhalter, das gilt nicht für alle ‘Static Final’ Primitiven bzw String Variablen, nur solche, die durch einen konstanten Ausdruck initialisiert werden.

    – Lew Bloch

    23. Mai 2017 um 0:54 Uhr

  • Ja, und das Feld muss nicht einmal sein static während dies ein häufiger Fall ist.

    – Raffael Winterhalter

    23. Mai 2017 um 5:40 Uhr

  • @RafaelWinterhalter aber beim Feld nicht staticbenötigen Sie einen Verweis auf eine Instanz davon (der Compiler bettet eine null-auch bei Verwendung des konstanten Werts danach überprüfen), also Lesen eines Nicht-static Das konstante Feld löst keine Klasseninitialisierung aus, aber die Initialisierung ist sowieso bereits erfolgt, als die Instanz erstellt wurde (wenn nicht sogar früher)

    – Holger

    8. April 2022 um 9:19 Uhr


Benutzeravatar von naikus
Naikus

Statische Felder werden während des initialisiert Initialisierung “Phase” des Klassenladens (Laden, Verknüpfen und Initialisieren), die statische Initialisierer und Initialisierungen ihrer statischen Felder enthält. Die statischen Initialisierer werden in einer in der Klasse definierten Textreihenfolge ausgeführt.

Betrachten Sie das Beispiel:

public class Test {

   static String sayHello()  {
      return a;
   }

   static String b = sayHello(); // a static method is called to assign value to b.
                                 // but its a has not been initialized yet.

   static String a = "hello";

   static String c = sayHello(); // assignes "hello" to variable c

    public static void main(String[] arg) throws Throwable {
         System.out.println(Test.b); // prints null
         System.out.println(Test.sayHello()); // prints "hello"
    }
}

Das Test.b wird gedruckt null denn wenn die sayHello Im statischen Bereich wurde die statische Variable aufgerufen a wurde nicht initialisiert.

  • Genau genommen ist die Initialisierung keine “Phase” des Klassenladens. In der Tat einige Klassen dürfen geladen, aber nie initialisiert werden, wenn die Anwendung sie nicht tatsächlich verwendet.

    – Stefan C

    17. August 2010 um 4:51 Uhr

  • @Stephen C Du hast Recht, ich habe es mangels eines besseren Begriffs verwendet, vielleicht werde ich es zitieren.

    – Naikos

    17. August 2010 um 5:09 Uhr

  • @StephenC bedeutet das, dass beim Laden der Klasse statischen Variablen (&-Methoden) Speicher zugewiesen wird, diese statischen Variablen jedoch nicht mit im Code bereitgestellten Werten initialisiert werden? denn hier schien es, wenn b->sayHello()->a, ‘a’ im Speicher ist, aber der Wert noch nicht zugewiesen ist.

    – Schabbir Essaji

    6. Februar 2018 um 7:36 Uhr

  • Grundsätzlich ja.

    – Stefan C

    6. Februar 2018 um 8:09 Uhr

  • @StephenC bitte, könntest du ein paar Details geben? Wie ich weiß, weist es in der Verknüpfungsphase Speicher für statische Variablen zu und weist ihnen einen Standardwert zu. Dann weist es ihnen in der Initialisierungsphase ursprüngliche Werte zu. In diesem Beispiel b ist null, weil in der Initialisierungsphase statische Blöcke von Eltern zu Kind und von oben nach unten ausgeführt werden.

    – Hayk Mkrtchyan

    24. Januar 2022 um 10:41 Uhr


Ja, alle statischen Initialisierer werden ausgeführt, bevor Sie zum ersten Mal auf die Klasse zugreifen. Wenn es anders wäre, würde ich es einen Bug nennen.

  • Es gibt Möglichkeiten, auf eine Klasse zu verweisen, ohne sie zu initialisieren.

    – Lew Bloch

    23. Mai 2017 um 0:56 Uhr

1444990cookie-checkWann erfolgt die statische Initialisierung?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy