Почему назначение short by byte работает только тогда, когда короткий является окончательным?
Может кто-нибудь объяснить, почему следующие компиляции:
final short s1 = 1;
final char c1 = 1;
byte b1 = s1;
byte b2 = c1;
Но следующее: (сообщение об ошибке компилятора Type mismatch: cannot convert from short to byte
):
short s1 = 1;
char c1 = 1;
byte b1 = s1;
byte b2 = c1;
Ответы
Ответ 1
Ответ находится в JLS - 5.2. Преобразование присваивания:
.. если выражение является константным выражением (§15.28) типа byte
, short
, char
или int
:
- Сужение примитивного преобразования может быть использовано, если тип переменной
byte
, short
или char
, а значение константное выражение представляется в типе переменной.
Когда вы пишете:
final short s1 = 1;
Значение выражения известно во время компиляции, и поскольку оно не может быть изменено, вам не нужно бросать.
Во втором фрагменте значение не известно во время компиляции - оно оценивается во время выполнения, поэтому вам потребуется явный листинг.
Если вы попытаетесь скомпилировать следующий код:
final byte b1 = 200;
final byte b2 = 200;
byte sum = b1 + b1;
Вы получите ошибку компиляции, так как значения с правой стороны известны компилятору, и он знает, что сумма не может вписаться в byte
.
Ответ 2
В первом примере компилятор знает, что s1
и c1
никогда не изменится и что их окончательное значение (1
) вписывается в byte
.
Во втором компилятор беспокоится о том, что произойдет, если s1
и c1
находятся вне 0..255
-128..127
, когда они были назначены переменной byte
и предупреждают вас что это небезопасно.
Если вы явно применяете их, как предлагает балалайка в комментариях, компилятор с облегчением понимает, что вы, кажется, знаете, что делаете (или, по крайней мере, у кого-то виноват, если все идет на юг) и позволяет это сделать.