Bis heute dachte ich zum Beispiel:
i += j;
War nur eine Abkürzung für:
i = i + j;
Aber wenn wir das versuchen:
int i = 5;
long j = 8;
Dann i = i + j;
wird nicht kompiliert, aber gut i += j;
kompiliert.
Bedeutet das, dass es sich tatsächlich i += j;
um eine Abkürzung für so etwas handelt
i = (type of i) (i + j)
?
java
casting
operators
variable-assignment
assignment-operator
Honza Brabec
quelle
quelle
i+=(long)j;
sogar gut kompiliert.i += (int) f;
Wirkt f vor dem Hinzufügen, daher ist es nicht gleichwertig.(int) i += f;
Wirkt das Ergebnis nach der Zuweisung, auch nicht gleichwertig. Es gibt keinen Platz für eine Besetzung, die anzeigt, dass Sie den Wert nach dem Hinzufügen, aber vor der Zuweisung umwandeln möchten.Antworten:
Wie immer bei diesen Fragen hat das JLS die Antwort. In diesem Fall §15.26.2 Compound Assignment Operators . Ein Auszug:
Ein Beispiel aus §15.26.2
Mit anderen Worten, Ihre Annahme ist richtig.
quelle
i+=j
compiliert , wie ich mich selbst überprüft, aber es würde zu einem Verlust an Präzision rechts führen? Wenn dies der Fall ist, warum kann es dann nicht auch in i = i + j passieren? Warum uns dort nerven?i += j
) sicherer ist anzunehmen, dass der Genauigkeitsverlust erwünscht ist, im Gegensatz zum anderen Fall (i = i + j
)E1 op= E2 is equivalent to E1 = (T)((E1) op (E2))
so etwas wie implizites Down-Typecasting (von Long nach Int). Während in i = i + j wir es explizit tun müssen, dh den(T)
Teil inE1 = ((E1) op (E2))
Ist es nicht?Ein gutes Beispiel für dieses Casting ist die Verwendung von * = oder / =
oder
oder
oder
quelle
A
;)ch += 32
= DSehr gute Frage. Die Java-Sprachspezifikation bestätigt Ihren Vorschlag.
quelle
double->float
als Erweiterung behandelt werden, auf der Grundlage, dass Werte vom Typfloat
reelle Zahlen weniger spezifisch identifizieren als solche vom Typdouble
. Wenn mandouble
als vollständige Postanschrift undfloat
als 5-stellige Postleitzahl betrachtet, ist es möglich, eine Anfrage nach einer Postleitzahl mit einer vollständigen Adresse zu erfüllen, aber es ist nicht möglich, eine Anfrage nach einer vollständigen Adresse mit nur einer Postleitzahl genau anzugeben . Das Umwandeln einer Adresse in eine Postleitzahl ist eine verlustbehaftete Operation, aber ...float->double
entspricht der Konvertierung der US-Postleitzahl 90210 in "US Post Office, Beverly Hills CA 90210".Ja,
im Grunde, wenn wir schreiben
Der Compiler konvertiert dies in
Ich habe gerade den
.class
Dateicode überprüft .Wirklich gut zu wissen
quelle
Sie müssen von bis umwandeln
long
,int
explicitly
falls diesi = i + l
dann kompiliert und die korrekte Ausgabe liefert. mögenoder
In diesem Fall
+=
funktioniert es jedoch einwandfrei, da der Operator implizit die Typumwandlung vom Typ der rechten Variablen zum Typ der linken Variablen durchführt und daher nicht explizit umgewandelt werden muss.quelle
int
durchgeführt wird, nachdem die+
. Der Compiler würde (sollte?) Wirft eine Warnung , wenn es wirklich hergegeben daslong
zuint
.Das Problem hierbei ist das Typgießen.
Wenn Sie int und long hinzufügen,
Ist
+=
aber so codiert, dass es Typ Casting macht.i=(int)(i+m)
quelle
In Java werden Typkonvertierungen automatisch durchgeführt, wenn der Typ des Ausdrucks auf der rechten Seite einer Zuweisungsoperation sicher zum Typ der Variablen auf der linken Seite der Zuweisung heraufgestuft werden kann. So können wir sicher zuordnen:
Das gleiche funktioniert nicht umgekehrt. Zum Beispiel können wir ein Long nicht automatisch in ein Int konvertieren, da das erste mehr Speicher benötigt als das zweite und folglich Informationen verloren gehen können. Um eine solche Konvertierung zu erzwingen, müssen wir eine explizite Konvertierung durchführen.
Typ - Konvertierung
quelle
long
2 mal größer alsfloat
.float
kann nicht jeden möglichenint
Wert enthalten, und adouble
kann nicht jeden möglichenlong
Wert enthalten.double d=33333333+1.0f;
ohne Beanstandung, obwohl das Ergebnis 33333332.0 wahrscheinlich nicht das ist, was beabsichtigt war (im Übrigen wäre die arithmetisch korrekte Antwort von 33333334.0f entwederfloat
oder darstellbarint
).Manchmal kann eine solche Frage bei einem Interview gestellt werden.
Zum Beispiel, wenn Sie schreiben:
Es gibt keine automatische Typumwandlung. In C ++ wird es keinen Fehler beim Kompilieren des obigen Codes geben, aber in Java erhalten Sie so etwas wie
Incompatible type exception
.Um dies zu vermeiden, müssen Sie Ihren Code folgendermaßen schreiben:
quelle
op
Verwendung in C ++ mit der Verwendung in Java. Ich mag es immer, diese Kleinigkeiten zu sehen, und ich denke, sie tragen etwas zu dem Gespräch bei, das oft ausgelassen wird.Der Hauptunterschied besteht darin, dass bei
a = a + b
keine Typumwandlung stattfindet und der Compiler sich über Sie ärgert, weil Sie keine Typumwandlung durchgeführt haben. Aber mita += b
, was es wirklich tut, ist Typografieb
auf einen Typ, der mit kompatibel ista
. Also wenn du es tustWas Sie wirklich tun, ist:
quelle
Subtiler Punkt hier ...
Es gibt eine implizite Typumwandlung für
i+j
whenj
ist ein Double undi
ist ein int. Java konvertiert IMMER eine Ganzzahl in ein Double, wenn zwischen ihnen eine Operation besteht.Um zu klären,
i+=j
woi
eine ganze Zahl undj
ein Doppel ist, kann beschrieben werden alsSiehe: diese Beschreibung des impliziten Castings
Sie könnten typisieren wollen ,
j
um(int)
für Klarheit in diesem Fall.quelle
int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;
. Das Hinzufügen von Null zusomeInt
sollte den Wert nicht beeinflussen, aber das HeraufstufensomeInt
zufloat
kann den Wert ändern.Java Language Specification definiert
E1 op= E2
äquivalent zu sein ,E1 = (T) ((E1) op (E2))
woT
ist eine ArtE1
undE1
wird einmal ausgewertet .Das ist eine technische Antwort, aber Sie fragen sich vielleicht, warum das so ist. Betrachten wir das folgende Programm.
Was druckt dieses Programm?
Hast du 3 erraten? Schade, dieses Programm wird nicht kompiliert. Warum? Nun, es kommt vor, dass das Hinzufügen von Bytes in Java definiert wird, um ein zurückzugeben
int
. Ich glaube, dies lag daran, dass die Java Virtual Machine keine Byte-Operationen zum Speichern von Bytecodes definiert (es gibt schließlich nur eine begrenzte Anzahl davon). Die Verwendung von Integer-Operationen ist stattdessen ein Implementierungsdetail, das in einer Sprache verfügbar gemacht wird.Aber wenn
a = a + b
es nicht funktioniert, würde das bedeuten, dass esa += b
niemals für Bytes funktionieren würde, wenn esE1 += E2
so definiert wäreE1 = E1 + E2
. Wie das vorige Beispiel zeigt, wäre dies tatsächlich der Fall. Als Hack, um den+=
Operator für Bytes und Shorts arbeiten zu lassen, ist eine implizite Umwandlung beteiligt. Es ist kein so großer Hack, aber während der Arbeit mit Java 1.0 lag der Schwerpunkt darauf, die Sprache zunächst freizugeben. Aufgrund der Abwärtskompatibilität konnte dieser in Java 1.0 eingeführte Hack nicht entfernt werden.quelle