Jeśli short
jest automatycznie promowany do int
w operacjach arytmetycznych, to dlaczego:
short thirty = 10 * 3;
Prawne przypisanie do short
zmiennej thirty
?
Z kolei to:
short ten = 10;
short three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED
tak dobrze jak to:
int ten = 10;
int three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED
nie kompiluje się, ponieważ przypisanie int
wartości do a short
nie jest dozwolone bez rzutowania zgodnie z oczekiwaniami.
Czy jest coś specjalnego w literałach liczbowych?
java
short
type-promotion
Gekon sufitowy
źródło
źródło
short thirty = 10 * 3;
jest najprawdopodobniej zastępowany przezshort thirty = 30;
kompilator, który jest wówczas prawidłową instrukcją. (Musiałbym jednak sprawdzić odpowiednią sekcję JLS).10 * 3
i inicjalizuje zmienną z wynikiem. W twoim niedziałającym przykładzie obliczenia są wykonywane w czasie wykonywania, gdzie JVM rzuca skrót.final int ten = 10; final int three = 3; short thirty = ten * three;
kompiluje się dobrze.If short is automatically promoted to int in arithmetic operations
- to nie ma znaczenia. Ani10
też nie3
są szorty, ani nie są promowane, są literały.10
i3
są oceniane jakoint
s przez kompilator?Odpowiedzi:
Ponieważ kompilator zastępuje
10*3
30 w czasie kompilacji . A więc skutecznie:short thirty = 10 * 3
jest obliczane w czasie kompilacji.Spróbuj zmienić
ten
ithree
nafinal short
(sprawić, by kompilowały stałe czasowe) i zobacz, co się stanie: PSprawdź kod bajtowy, używając
javap -v
obu wersji (10*3
ifinal short
). Będziesz mógł zobaczyć, że różnica jest niewielka.Ok, oto różnica w kodzie bajtów dla różnych przypadków.
Przypadek 1 :
Kod bajtu:
Przypadek -2:
Kod bajtu:
Przypadek -3:
Kod bajtu:
W powyższym przypadku
10
i3
są pobierane ze zmiennych lokalnychs1
is2
źródło
Try changing ten and three to final short
ćwiczenia :)you will see that there's no difference (between those two lines in the decompiled code)
ponieważ nie o to ci chodzi?case 10*3:
i podobnie jest legalne w konstrukcji przełącznika.Tak, dzieje się coś specjalnego w przypadku literału:
10 * 3
zostanie sprawdzone w czasie kompilacji . Więc nie potrzebujesz jawnej(short)
konwersji dla zwielokrotnionych literałów.ten * three
nie podlega ocenie w czasie kompilacji, dlatego wymaga jawnej konwersji.Byłoby inaczej, gdyby
ten
ithree
zostały oznaczonefinal
.źródło
Poniższa odpowiedź dodaje sekcję JLS i kilka szczegółów na temat tego zachowania.
Zgodnie z JLS §15.2 - Formy wyrażeń
źródło