Ja, dieses Verhalten ist hier gut definiert.
>Kurz gesagt, zitierend von diesem Link
Die Initialisierung einer Klasse oder Schnittstelle besteht in der Ausführung der Klassen- oder Schnittstelleninitialisierungsmethode
<clinit>
...
Eine Klasse oder Schnittstelle kann nur als Ergebnis initialisiert werden:
Die Ausführung einer der Java Virtual Machine-Anweisungen new, getstatic, putstatic oder invokestatic, die auf die Klasse oder Schnittstelle verweist (§neu, §getstatisch, §putstatisch, §invokestatisch). Alle diese Anweisungen verweisen direkt oder indirekt über eine Feldreferenz oder eine Methodenreferenz auf eine Klasse.
Bei der Ausführung einer neuen Anweisung wird die referenzierte Klasse oder Schnittstelle initialisiert, wenn sie nicht bereits initialisiert wurde.
Bei der Ausführung einer getstatic-, putstatic- oder invokestatic-Anweisung wird die Klasse oder Schnittstelle, die das aufgelöste Feld oder die Methode deklariert hat, initialisiert, wenn sie nicht bereits initialisiert wurde.
Der erste Aufruf einer java.lang.invoke.MethodHandle-Instanz, die das Ergebnis der Auflösung eines Methoden-Handles durch die Java Virtual Machine (§5.4.3.5) war und eine Art von 2 (REF_getStatic), 4 ( REF_putStatic) oder 6 (REF_invokeStatic).
Aufruf bestimmter reflektiver Methoden in der Klassenbibliothek (§2.12), zum Beispiel in der Klasse Class oder im Paket java.lang.reflect.
Die Initialisierung einer seiner Unterklassen.
Seine Bezeichnung als anfängliche Klasse beim Start der Java Virtual Machine (§5.2).
Die <clinit>
-Methode ist die Methode (vom Compiler erstellt), die statische Variablen initialisiert und den Code enthält, den Sie in den static
-Block
Wenn in Ihrem Fall der static
-Block der Klasse B
läuft (was <clinit>
tun wird), wird es einen getStatic
opcode haben, der A.HOST
anfordert. Daher wird die Initialisierung von A
ausgelöst und A.HOST
initialisiert. So lesen Sie den richtigen Wert.
Der statische Block für eine Klasse wird ausgeführt, wenn
class is accessed
ist, um entweder eine Instanz zu erstellen oder um auf eine statische Methode zuzugreifen oder Feld.
Das hängt von dem Code ab, den wir ausführen.
In Ihrem Fall, wenn wir A.HOST
ausführen, ruft es auch den statischen Block von class A
auf.
Lesen Sie dies
Der statische Initialisierer für eine Klasse wird ausgeführt, wenn die Klasse das erste Mal ist aufgerufen, um entweder eine Instanz zu erstellen oder um auf eine statische Methode zuzugreifen oder Feld.
Quelle: In welcher Reihenfolge blockieren statische Initialisierer in Java ausführen?
Tags und Links java language-lawyer