Wenn short
wird automatisch befördert int
in arithmetischen Operationen, warum ist dann:
short thirty = 10 * 3;
Eine rechtliche Abtretung an die short
Variable thirty
?
Das wiederum:
short ten = 10;
short three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED
so gut wie das:
int ten = 10;
int three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED
wird nicht kompiliert, da eine zugewiesen wird int
Wert zu a short
ist nicht erlaubt, ohne wie erwartet zu werfen.
Gibt es etwas Besonderes bei numerischen Literalen?
Weil der Compiler ersetzt 10*3
mit 30 at Kompilierzeit selbst. Also effektiv: short thirty = 10 * 3
wird zur Kompilierzeit berechnet.
Versuchen Sie, sich zu ändern ten
und three
zu final short
(wodurch sie Zeitkonstanten kompilieren) und sehen, was passiert: P
Untersuchen Sie den Bytecode mit javap -v
für beide Versionen (10*3
und final short
). Sie werden sehen, dass es kaum Unterschiede gibt.
Ok, hier ist also der Bytecode-Unterschied für verschiedene Fälle.
Fall 1 :
Java-Code: main() {short s = 10*3; }
Bytecode:
stack=1, locals=2, args_size=1
0: bipush 30 // directly push 30 into "s"
2: istore_1
3: return
Fall -2 :
public static void main(String arf[]) {
final short s1= 10;
final short s2 = 3;
short s = s1*s2;
}
Bytecode:
stack=1, locals=4, args_size=1
0: bipush 10
2: istore_1
3: iconst_3
4: istore_2
5: bipush 30 // AGAIN, push 30 directly into "s"
7: istore_3
8: return
Fall -3 :
public static void main(String arf[]) throws Exception {
short s1= 10;
short s2 = 3;
int s = s1*s2;
}
Byte-Code :
stack=2, locals=4, args_size=1
0: bipush 10 // push constant 10
2: istore_1
3: iconst_3 // use constant 3
4: istore_2
5: iload_1
6: iload_2
7: imul
8: istore_3
9: return
Im oben genannten Fall 10
und 3
werden den lokalen Variablen entnommen s1
und s2
Ja, es gibt etwas Besonderes mit dem wörtlichen Fall: 10 * 3
wird mit bewertet kompilieren Zeit. Sie brauchen also keine explizite (short)
Konvertierung für multiplizierte Literale.
ten * three
ist nicht zur Kompilierzeit auswertbar und benötigt daher eine explizite Konvertierung.
Es wäre eine andere Sache, wenn ten
und three
markiert waren final
.
Die folgende Antwort fügt den JLS-Abschnitt und einige Details zu diesem Verhalten hinzu.
Gem JLS §15.2 – Ausdrucksformen
Einige Ausdrücke haben einen Wert, der zur Kompilierzeit bestimmt werden kann. Dies sind konstante Ausdrücke (§15.28).
short thirty = 10 * 3;
wird höchstwahrscheinlich ersetzt durchshort thirty = 30;
vom Compiler, was dann eine gültige Aussage ist. (Ich müsste jedoch den relevanten JLS-Abschnitt nachschlagen).– Thomas
25. August 2015 um 12:02 Uhr
Der Compiler rechnet
10 * 3
und initialisiert die Variable mit dem Ergebnis. In Ihrem nicht funktionierenden Beispiel erfolgt die Berechnung zur Laufzeit, wo die JVM den Kurzschluss auslöst.– Felix
25. August 2015 um 12:03 Uhr
Ich denke, dies ist ein Duplikat von stackoverflow.com/questions/30346587/java-char-to-byte-casting oder stackoverflow.com/questions/9379983/… . Allerdings: Beachten Sie das
final int ten = 10; final int three = 3; short thirty = ten * three;
kompiliert gut.– Marco13
25. August 2015 um 12:46 Uhr
If short is automatically promoted to int in arithmetic operations
– das ist nicht relevant. Weder10
Noch3
sind Shorts noch werden sie gefördert, sie sind wörtlich.– Matthäus Lesen
25. August 2015 um 18:36 Uhr
@MatthewRead: Aber selbst als Literale müssen sie als bestimmter Datentyp ausgewertet werden, oder? Also stimmt das
10
und3
werden bewertet alsint
s vom Compiler?– LarsH
26. August 2015 um 16:31 Uhr