Ich frage mich, wann statische Variablen auf ihre Standardwerte initialisiert werden. Ist es richtig, dass beim Laden einer Klasse statische Variablen erstellt (zugewiesen) und dann statische Initialisierer und Initialisierungen in Deklarationen ausgeführt werden? Ab wann werden die Standardwerte angegeben? Dies führt zu dem Problem der Vorwärtsreferenz.
Bitte auch, wenn Sie dies anhand der Frage erklären können, warum statische Felder nicht rechtzeitig initialisiert werden. und besonders die Antwort von Kevin Brock auf derselben Seite. Ich kann den 3. Punkt nicht verstehen.
java
static
initialization
Ankit
quelle
quelle
Antworten:
Von Siehe Java Static Variable Methoden :
Instanz- und Klassenvariablen (statisch) werden automatisch auf Standardstandardwerte initialisiert, wenn Sie sie nicht absichtlich initialisieren. Obwohl lokale Variablen nicht automatisch initialisiert werden, können Sie kein Programm kompilieren, das weder eine lokale Variable initialisiert noch dieser lokalen Variablen einen Wert zuweist, bevor sie verwendet wird.
Was der Compiler tatsächlich tut, ist, intern eine einzelne Klasseninitialisierungsroutine zu erstellen, die alle statischen Variableninitialisierer und alle statischen Initialisierungscodeblöcke in der Reihenfolge kombiniert, in der sie in der Klassendeklaration erscheinen. Diese einzelne Initialisierungsprozedur wird nur einmal automatisch ausgeführt, wenn die Klasse zum ersten Mal geladen wird.
Bei inneren Klassen können sie keine statischen Felder haben
Siehe JLS 8.1.3 Innere Klassen und umschließende Instanzen
final
Felder in Java können getrennt von ihrem Deklarationsort initialisiert werden. Dies gilt jedoch nicht fürstatic final
Felder. Siehe das folgende Beispiel.Dies ist , weil es nur eine ist Kopie der
static
Variablen , die mit der Art, anstatt eines mit jeder Instanz des Typs zugeordnet ist, wie mit Instanzvariablen und wenn wir versuchen , initialisierenz
vom Typstatic final
innerhalb des Konstruktor, es wird versuchen , das neu zu initialisierenstatic final
Typ - Feldz
weil der Konstruktor bei jeder Instanziierung der Klasse ausgeführt wird, die bei statischenfinal
Feldern nicht auftreten darf .quelle
In case of static inner classes, they can not have static fields
scheint ein Tippfehler. Innere Klassen sind nicht statisch.Sehen:
Insbesondere der letzte enthält detaillierte Initialisierungsschritte , die angeben, wann und in welcher Reihenfolge statische Variablen initialisiert werden (mit der Einschränkung, dass
final
Klassenvariablen und Schnittstellenfelder, die Konstanten zur Kompilierungszeit sind, zuerst initialisiert werden).Ich bin mir nicht sicher, was Ihre spezifische Frage zu Punkt 3 ist (vorausgesetzt, Sie meinen die verschachtelte?). Die detaillierte Sequenz besagt, dass dies eine rekursive Initialisierungsanforderung wäre, sodass die Initialisierung fortgesetzt wird.
quelle
Statische Felder werden initialisiert, wenn die Klasse vom Klassenladeprogramm geladen wird. Zu diesem Zeitpunkt werden Standardwerte zugewiesen. Dies erfolgt in der Reihenfolge, in der sie im Quellcode erscheinen.
quelle
Die Reihenfolge der Initialisierung lautet:
Die Details des Prozesses werden im JVM- Spezifikationsdokument erläutert .
quelle
statische Variable
quelle
Beginnend mit dem Code aus der anderen Frage:
Ein Verweis auf diese Klasse startet die Initialisierung. Zunächst wird die Klasse als initialisiert markiert. Dann wird das erste statische Feld mit einer neuen Instanz von MyClass () initialisiert. Beachten Sie, dass myClass sofort einen Verweis auf eine leere MyClass-Instanz erhält . Das Leerzeichen ist vorhanden, aber alle Werte sind null. Der Konstruktor wird jetzt ausgeführt und gedruckt
obj
, was null ist.Nun zurück zur Initialisierung der Klasse: Es
obj
wird auf ein neues reales Objekt verwiesen, und wir sind fertig.Wenn dies durch eine Anweisung wie:
MyClass mc = new MyClass();
ausgelöst wurde, wird erneut Platz für eine neue MyClass-Instanz zugewiesen (und die Referenz in platziertmc
). Der Konstruktor wird erneut ausgeführt und erneut gedrucktobj
, was jetzt nicht null ist.Der eigentliche Trick dabei ist, dass bei der Verwendung von
new
wie inWhatEverItIs weii = new WhatEverItIs( p1, p2 );
weii
sofort ein Verweis auf ein Bit des nullten Speichers gegeben wird. Die JVM initialisiert dann die Werte und führt den Konstruktor aus. Wenn Sie jedochweii
vorher irgendwie darauf verweisen - beispielsweise durch Verweisen auf einen anderen Thread oder durch Verweisen auf die Klasseninitialisierung -, sehen Sie sich eine mit Nullwerten gefüllte Klasseninstanz an.quelle
Die statische Variable kann auf die folgenden drei Arten initialisiert werden: Wählen Sie eine beliebige aus
oder Sie können dies tun, indem Sie einen statischen Block erstellen, z.
Es gibt eine Alternative zu statischen Blöcken - Sie können eine private statische Methode schreiben
quelle