Könnte jemand erklären, wie Java diesen Code ausführt? Ich meine die Reihenfolge der Ausführung jeder Anweisung.
public class Foo
{
boolean flag = sFlag;
static Foo foo = new Foo();
static boolean sFlag = true;
public static void main(String[] args)
{
System.out.println(foo.flag);
}
}
AUSGABE:
false
Antworten:
foo
ist null undsFlag
falschfoo
) wird ausgeführt:Foo
wird erstelltflag
Executes - ist derzeitsFlag
false, daher ist der Wert vonflag
falsesFlag
) wird ausgeführt und setzt den Wert auf truemain
läuft, druckt ausfoo.flag
, was falsch istBeachten Sie, dass wenn
sFlag
es als solche deklariertfinal
würde, es als Kompilierungszeitkonstante behandelt würde. Zu diesem Zeitpunkt würden alle Verweise darauf im Grunde genommen inline seintrue
,foo.flag
was auch wahr wäre.quelle
flag
wurde nach definiertsflag
?sFlag
vor dem erklärt wurdefoo
, dass Materie würde - abersFlag
undflag
Ordnung spielt keine Rolle.foo
wird während der statischen Initialisierung der Klasse und vor der Initialisierung von sFlag instanziiert, und der Standardwert eines Booleschen Werts ist false.Foo wird für die Instanz initialisiert
2.a Das Instanzmitgliedsflag wird auf den Wert von sFlag initialisiert (
false
standardmäßig).Weitere Informationen finden Sie in JLS §12.4 .
quelle
Wenn die Klasse geladen wird
sFlag
und diefoo
Felder initialisiert werden,foo
wird sie zuerst initialisiert!Felder
flag
undsFlag
sind boolesch und können nicht null sein. Standardmäßig sind sie also falsch undsFlag
beifoo
der Initialisierung immer noch falsch .flag = sFlag
danachflag
ist falsch. Das ist esquelle
Die allgemeine Reihenfolge der Initialisierungsoperationen lautet (nach dem Laden der Klasse und vor der ersten Verwendung):
Sicherlich bezeichne ich Konstruktoren und Funktionskörper oben nicht als Codeblock .
Ich weiß nicht wie über
final static
Felder. Es sieht so aus, als ob sie den Regeln derstatic
Felder folgen und vor der Deklaration nicht referenziert werden können, obwohl zuvor kommentiert wurde, dass sie beim Kompilierungsschritt initialisiert wurden. Wenn auf sie verwiesen wird, bevor ein Kompilierungsfehler auftritt:Example.java:8: illegal forward reference System.err.println("1st static block j=" + j);
Möglicherweise können
final static
Felder initialisiert und in die Klassendatei kompiliert werden, dies ist jedoch keine allgemeine Regel und kann vor der Deklaration immer noch nicht referenziert werden.Beispielcode zur Überprüfung der Initialisierungsreihenfolge:
class Example { final static int j = 5; { System.err.println("1st initializer j=" + j); } static { System.err.println("1st static block j=" + j); } static { System.err.println("2nd static block j=" + j); } final static java.math.BigInteger i = new java.math.BigInteger("1") { { System.err.println("final static anonymous class initializer"); } }; Example() { System.err.println("Constructor"); } static { System.err.println("3nd static block j=" + j); } { System.err.println("2nd initializer"); } public static void main(String[] args) { System.err.println("The main beginning."); Example ex = new Example(); System.err.println("The main end."); } }
Das obige Code-Snipset wird gedruckt:
1st static block j=5 2nd static block j=5 final static anonymous class initializer 3nd static block j=5 The main beginning. 1st initializer j=5 2nd initializer Constructor The main end.
quelle
zuerst sollten statische Felder laufen und zuerst inline! In der ersten Zeile 4 und dann wird 5 ausgeführt, sodass foo zuerst initialisiert wird. Wie wir wissen, werden boolesche Variablen standardmäßig auf false initialisiert. Wenn also foo initialisiert wird, ist das Flag-Feld zunächst sflag, das false ist, und dann wird sfalsg true Flag wird nicht geändert (es gibt keine Beziehung), dann endlich Hauptläufe und Falg drucken, das ist falsch !!! Ich hoffe nützlich zu sein! Erfolgreich sein
quelle