Ich entdeckte Java's + =, - =, * =, / = zusammengesetzte Zuweisungsoperatoren (gute Frage :)) , aber es hatte einen Teil, den ich nicht ganz verstehe. Entlehnung von dieser Frage:
%Vor%Dann wird
i = i + l;
nicht kompiliert, aberi += l;
wird kompiliert.
Die akzeptierte Antwort auf die verknüpfte Frage besagt:
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 nur einmal bewertet wird. p>
was bedeutet, dass i += l;
dasselbe ist wie i = (int)((i) + (l));
mit der Ausnahme, dass i
nur einmal ausgewertet wird.
A long
kann sein (IIRC ist sogar garantiert) länger als ein int
und kann daher einen viel größeren Wertebereich enthalten.
Da diese Situation sehr leicht zu Datenverlusten führen kann, weil während der Ausführung der Anweisung (entweder r-value-Ausdruckauswertung oder -zuweisung) die Konvertierung zu einem bestimmten Zeitpunkt eingeschränkt wird, ist i += l;
kein Kompilierungsfehler oder zumindest Warnung?
Angesichts der Tatsache, dass diese Situation sehr leicht zu Datenverlusten führen kann, weil während der Ausführung der Anweisung (entweder r-value-Ausdruckauswertung oder -zuweisung) an einer bestimmten Stelle die Konvertierung eingeschränkt wird, ist i + = l; kein Kompilierfehler oder zumindest eine Warnung?
Es sollte wahrscheinlich, wie Sie sagten, entweder ein Kompilierungsfehler oder zumindest eine Warnung sein. Die meisten Bücher und Tutorials, die mir bekannt sind, führen x += y;
als Kurzschrift für x = x + y;
ein. Ich weiß ehrlich gesagt nichts von dem, was die im Abschnitt 15.26.2 Zusammengesetzte Zuweisungsoperatoren der JLS mit Ausnahme einer.
In Kapitel 2 (Puzzle 9) von Java Puzzlers: Fallen, Fallstricke und Eckfälle den Autoren ( Joshua Bloch und Neal Gafter) bitten Sie, Deklarationen für x
und i
anzugeben, so dass dies eine rechtliche Aussage ist:
und das ist nicht:
%Vor% Es gibt viele Lösungen, einschließlich der ersten zwei Codezeilen, die Sie in Ihrer Frage gepostet haben. Die Autoren warnen davor, zusammengesetzte Zuweisungsoperatoren für Variablen vom Typ byte
, short
und char
zu verwenden und empfehlen, dass bei Verwendung dieser Operatoren für Variablen vom Typ int
sichergestellt werden sollte, dass der RHS-Ausdruck kein a ist long
, float
oder double
.
Sie schließen mit der folgenden Beobachtung (Hervorhebung von mir):
Zusammenfassend generieren zusammengesetzte Zuweisungsoperatoren automatisch einen Cast. Wenn der Typ des Ergebnisses der Berechnung breiter ist als der der Variablen, ist der generierte Cast ein gefährlicher Narrowcast. Solche Modelle können die Präzision oder Größe stillschweigend verwerfen. Für Sprachdesigner ist es wahrscheinlich ein Fehler, wenn zusammengesetzte Zuweisungsoperatoren unsichtbare Umwandlungen erzeugen; Verbundzuordnungen, bei denen die Variable einen schmaleren Typ hat als das Ergebnis der Berechnung, sollten wahrscheinlich illegal sein.
Grundsätzlich, weil i += l
so kompiliert wird, als wäre es i = (int) (i + l)
geschrieben. Es gibt ähnliche "Überraschungen" beim Hinzufügen von int
-Werten zu byte
und char
Variablen - der Zuweisungsoperator funktioniert, während der einfache Additionsoperator nicht funktioniert.
Der Grund dafür ist, dass Sie Folgendes tun können:
%Vor%Wenn + = zu b = b + 1 erweitert wurde, dann würde der Ausdruck keine Überprüfung geben, weil der Ausdruck "b + 1" vom Typ int ist. Alle Integralausdrücke in Java sind mindestens der Int-Typ, selbst wenn Sie zwei Bytes zusammenfügen.
%Vor%Tags und Links java variable-assignment compound-operator