2016-02-04 6 views
37

Czy ktoś mógłby wyjaśnić, dlaczego następujące kompiluje:Dlaczego przypisywanie skrótu do bajtu działa tylko wtedy, gdy skrót jest ostateczny?

final short s1 = 1; 
final char c1 = 1; 
byte b1 = s1; 
byte b2 = c1; 

Ale po nie (Komunikat o błędzie kompilatora jest Type mismatch: cannot convert from short to byte):

short s1 = 1; 
char c1 = 1; 
byte b1 = s1; 
byte b2 = c1; 
+0

Co mówi Twój kompilator? – Idos

+0

Niezgodność typu: nie można przekonwertować z krótkiego na bajtowy – MATH000

+0

@balalaika Sądzę, że rozumie, że potrafi obsadować. Pyta, dlaczego pierwsze 4 wiersze nie powodują problemu dla kompilatora. – GhostCat

Odpowiedz

47

Odpowiedź jest w JLS - 5.2. Assignment Conversion:

.. Jeśli wyrażenie jest stała wyrażenie (§15.28) typu byte, short, char lub int:

  • Przewężenie prymitywny Konwersja może być użyta, jeśli typ zmiennej to byte, short lub char, oraz wartość stałego wyrażenia jest reprezentowalna w typie zmiennej.

Kiedy piszesz:

final short s1 = 1; 

Wartość wyrażenia jest znany w czasie kompilacji, a ponieważ nie mogą być zmieniane nie trzeba oddawać.

W Twoim drugim fragmencie wartość nie jest znana podczas kompilacji - jest oceniana w runtime, więc będziesz potrzebować wyraźnej obsady.


Jeśli spróbujesz skompilować następujący kod:

final byte b1 = 200; 
final byte b2 = 200; 
byte sum = b1 + b1; 

Dostaniesz kompilacji błąd od wartości przy prawej stronie są znany do kompilatora i wie, że suma nie mieści się w byte.

17

W pierwszej próbie, kompilator wie, że s1 i c1 nigdy się nie zmieni, a ich ostateczna wartość (1) pasuje do byte.

W drugim, kompilator martwi się, co by się stało, gdyby s1 i c1 były poza 0..255 -128..127 gdy zostały one przypisane do zmiennej byte i ostrzega, że ​​jest to niebezpieczne.

Jeśli jawnie rzucisz je jako bałałajkę sugeruje w komentarzach, kompilator odczuwa ulgę, że wydajesz się wiedzieć, co robisz (lub przynajmniej, że ma kogoś, kogo winić, jeśli sprawy idą na południe), i pozwala ci to zrobić to.

+0

Niesamowite!Czy możesz wskazać wyjaśnienie na temat tej "cechy" w JLS? –

+0

Czy możesz również wyjaśnić, dlaczego to: 'final long s1 = 1; int x = s1; 'nie działa? – MATH000

+5

Nie mogę. Proste wyjaśnienie jest następujące: JLS zezwala tylko na 'bajt',' short', 'char' i' int' (awesome find, Maroun Maroun - +1!). Jednakże, ale nie dostarcza żadnego wyjaśnienia tego lub pominięcia słowa 'long'. Moje wyjaśnienie ma dla mnie sens; ale nie rozumiem, dlaczego "długo" nie może zachowywać się w ten sam sposób. – Amadan

Powiązane problemy