Was passiert im folgenden Beispiel eigentlich?
%Vor% Die Ausgabe ist 3, aber ich wollte wissen, was tatsächlich unter den Abdeckungen passiert.
Zum Beispiel weiß ich, dass runde Klammern eine höhere Priorität haben als +
, was zuerst passiert (a = 2). Der Ausdruck sollte a = 2 + 2
werden.
Zur Laufzeit sollte zuerst der Ausdruck in Klammern ausgeführt werden und dann wird a zu 2. Es scheint, dass das erste a
auf der linken Seite zu +
vor (a = 2)
"geladen" wird und dieser letzte Ausdruck scheint das nicht zu überschreiben vorheriges Laden
Mit anderen Worten, ich bin ziemlich verwirrt, was genau hinter den Kulissen passiert.
Wenn jemand weiß, vielen Dank im Voraus.
Siehe das referenzierte Beispiel 15.7.1-2 von Ссылка , das ist fast identisch mit dem von Ihnen angegebenen Beispiel. Insbesondere:
Wenn der Operator ein Verbindungszuweisungsoperator ist (§15.26.2), dann Auswertung des linken Operanden beinhaltet das Erinnern an den Variable, die der linke Operand angibt und holen und speichern Der Wert dieser Variablen für die implizite binäre Operation.
Wegen dieser Priorität wird die linke Hand von + = zuerst ausgewertet.
Es kann für Sie aufgrund der Klammern verwirrend sein, beachten Sie jedoch den Abschnitt zur Auswertung der Klammern: Ссылка , und insbesondere:
Die Programmiersprache Java respektiert die Reihenfolge der Auswertung explizit durch Klammern und implizit durch den Operator angegeben Vorrang.
In diesem Fall gibt die durch den Operator + = angegebene implizite Priorität an, dass der linke Operand gemäß der Spezifikation gespeichert wird. Während es zutrifft, dass Zuweisungsoperatoren, einschließlich "+=", die niedrigste Priorität haben, gibt die Spezifikation für + = an, dass der linke Operand gemäß 15.26.2 gespeichert wird.
Aus dem JLS Abschnitt §15.26.2 Compound Assignment Operators :
Ein zusammengesetzter Zuordnungsausdruck der Form E1 op = E2 ist äquivalent zu E1 = (T) ((E1) op (E2)), wobei T der Typ von E1 ist, außer dass E1 wird nur einmal ausgewertet.
Also für Ihr Beispiel haben wir:
%Vor%Mit dem Ausdruck von links nach rechts ausgewertet. Daher die Ausgabe von 3
Schauen wir uns den Bytecode des folgenden Programms an:
%Vor%Wir müssen nur diesen Befehl ausführen:
%Vor%um den folgenden Bytecode zu erhalten:
%Vor% Erläuterung:
Wir konzentrieren uns nur auf die zwei Zeilen innerhalb der Hauptmethode:
%Vor% [ int a = 1;
beginnt hier]
1
auf den Stapel. variable 1
( variable 1
steht für a
) [ int a = 1;
endet hier]
[ a += (a = 2);
beginnt hier]
variable 1
und schiebt ihn auf den Stack. 2
auf den Stapel. variable 1
. variable 1
. [ a += (a = 2);
endet hier]
Fazit:
a = a + (a = 2)
wird über mehrere Operationen ausgeführt. 2: iload_1
wird als erster Befehl von a += (a = 2);
ausgeführt, der den ersten Operanden der Gleichung a = a + (a = 2)
liest und auf den Stack drückt.
Als nächstes werden 3: iconst_2
und 4: dup
ausgeführt, die im Prinzip 2
zweimal auf den Stapel schieben; eine für das Laden in a
und die andere als zweiter Operand. Danach wird 5: istore_1
ausgeführt, welches 2
in a
( a = 2
) lädt.
Schließlich werden 6: iadd
und 7: istore_1
ausgeführt, wobei 6: iadd
den ersten und den zweiten Operanden hinzufügt und das Ergebnis auf den Stapel verschiebt, und 7: istore_1
öffnet das Ergebnis und lädt es in a
.
Der Einfachheit halber lassen Sie uns einen kurzen Blick auf diesen Code werfen:
%Vor%und hier ist der Bytecode:
%Vor%Wie Sie sehen können, macht es einfach folgendes:
1
in a
. 3
in b
. a
und dann b
auf den Stapel. a
. Tags und Links java runtime variable-assignment