Ich bin nicht sicher, ob die Java-Sprachspezifikation ein Element enthält, das das Laden des vorherigen Werts einer Variablen vorschreibt ...
Es gibt. Wenn Sie das nächste Mal unklar sind, was in der Spezifikation steht, lesen Sie bitte die Spezifikation und stellen Sie dann die Frage, ob sie unklar ist.
... die rechte Seite, (x = y)
die in der durch Klammern angegebenen Reihenfolge zuerst berechnet werden sollte.
Diese Aussage ist falsch. Klammern implizieren keine Reihenfolge der Bewertung . In Java ist die Reihenfolge der Auswertung unabhängig von Klammern von links nach rechts. Klammern bestimmen, wo sich die Unterausdrucksgrenzen befinden, nicht die Reihenfolge der Auswertung.
Warum wird der erste Ausdruck als falsch, der zweite als wahr bewertet?
Die Regel für den ==
Operator lautet: Bewerten Sie die linke Seite, um einen Wert zu erzeugen, bewerten Sie die rechte Seite, um einen Wert zu erzeugen, vergleichen Sie die Werte, der Vergleich ist der Wert des Ausdrucks.
Mit anderen Worten, die Bedeutung von expr1 == expr2
ist immer dieselbe, als ob Sie geschrieben temp1 = expr1; temp2 = expr2;
und dann ausgewertet hätten temp1 == temp2
.
Die Regel für den =
Operator mit einer lokalen Variablen auf der linken Seite lautet: Auswerten der linken Seite, um eine Variable zu erzeugen, Auswerten der rechten Seite, um einen Wert zu erzeugen, Ausführen der Zuweisung, Ergebnis ist der zugewiesene Wert.
Also setze es zusammen:
x == (x = y)
Wir haben einen Vergleichsoperator. Bewerten Sie die linke Seite, um einen Wert zu erhalten - wir erhalten den aktuellen Wert von x
. Bewerten Sie die rechte Seite: Dies ist eine Zuweisung, also bewerten wir die linke Seite, um eine Variable zu erzeugen - die Variable x
- wir bewerten die rechte Seite - den aktuellen Wert von y
- weisen Sie sie zu x
, und das Ergebnis ist der zugewiesene Wert. Wir vergleichen dann den ursprünglichen Wert von x
mit dem zugewiesenen Wert.
Sie können (x = y) == x
als Übung tun . Denken Sie auch hier daran, dass alle Regeln für die Bewertung der linken Seite vor allen Regeln für die Bewertung der rechten Seite gelten .
Ich hätte erwartet, dass (x = y) zuerst ausgewertet wird, und dann würde es x mit sich selbst vergleichen (3) und true zurückgeben.
Ihre Erwartung basiert auf einer Reihe falscher Überzeugungen über die Regeln von Java. Hoffentlich haben Sie jetzt die richtigen Überzeugungen und werden in Zukunft wahre Dinge erwarten.
Diese Frage unterscheidet sich von "Reihenfolge der Auswertung von Unterausdrücken in einem Java-Ausdruck".
Diese Aussage ist falsch. Diese Frage ist völlig deutsch.
x ist hier definitiv kein "Unterausdruck".
Diese Aussage ist auch falsch. Es ist in jedem Beispiel zweimal ein Unterausdruck .
Es muss für den Vergleich geladen werden, anstatt "ausgewertet" zu werden.
Ich habe keine Ahnung, was das bedeutet.
Anscheinend haben Sie immer noch viele falsche Überzeugungen. Mein Rat ist, dass Sie die Spezifikation lesen, bis Ihre falschen Überzeugungen durch wahre Überzeugungen ersetzt werden.
Die Frage ist Java-spezifisch und der Ausdruck x == (x = y) stammt im Gegensatz zu weit hergeholten unpraktischen Konstrukten, die üblicherweise für knifflige Interviewfragen erstellt wurden, aus einem echten Projekt.
Die Herkunft des Ausdrucks ist für die Frage nicht relevant. Die Regeln für solche Ausdrücke sind in der Spezifikation klar beschrieben; Lies es!
Es sollte ein einzeiliger Ersatz für die Vergleichs- und Ersetzungssprache sein
Da dieser einzeilige Ersatz bei Ihnen, dem Leser des Codes, große Verwirrung stiftete, würde ich vorschlagen, dass dies eine schlechte Wahl war. Es ist kein Gewinn, den Code präziser, aber schwerer zu verstehen. Es ist unwahrscheinlich, dass der Code schneller wird.
Im Übrigen verfügt C # über eine Vergleichs- und Ersetzungsmethode als Bibliotheksmethode, die auf eine Maschinenanweisung reduziert werden kann . Ich glaube, Java hat keine solche Methode, da sie im Java-Typsystem nicht dargestellt werden kann.