Если вы ссылаетесь на JLS Sec 15.18.2 , в котором рассматривается добавление числовых типов, то в нем говорится:
Двоичное числовое продвижение выполняется над операндами (§5.6.2).
...
Типом аддитивного выражения числовых операндов является продвинутый тип его операндов.
JLS Sec5.6.2 описывает двоичное числовое продвижение :
Если какой-либо операнд имеет ссылочный тип, он подвергается преобразованию без распаковки (§5.1.8).
Преобразование растущего примитива (§5.1.2) применяется для преобразования одного или обоих операндов, как указано в следующих правилах:
Если один из операндов имеет тип double, другой преобразуется в двойной.
В противном случае, если один из операндов имеет тип float, другой преобразуется в float.
В противном случае, если один из операндов имеет тип long, другой преобразуется в long.
OtheВ противном случае оба операнда преобразуются в тип int.
Так, в случае int
и long
(где оба операнда имеютэтот тип), двоичное числовое продвижение является недопустимым: операнды остаются int
и long
соответственно, а результат добавления - int
и long
соответственно, то есть результат может быть назначен переменнымэтот тип.
В случае byte
и short
двоичное числовое продвижение приводит к расширению обоих из них до int
для выполнения сложения, и результат сложения равен int
;Вы должны явно привести обратно к более узкому типу, потому что не все значения int
вписываются в byte
или short
.
Из этого требования есть 2 исключения для выполнения явного
Во-первых, составные назначения: это сработало бы:
b += a;
, потому что, как указано в JLS Sec 15.26.2 :
Составное выражение присваивания в форме E1 op= E2
эквивалентно E1 = (T) ((E1) op (E2))
, где T
- это тип E1
, за исключением того, что E1
вычисляется только один раз.
Другими словами: компилятор вставляет приведение для вас:
b = (byte) ((b) + (a));
Во-вторых, если операнды имеют постоянные значения и известно, что результат сложения вписывается в диапазон более узкого типа, и вы выполняете присваивание в объявлении переменной.
Например:
final byte a=10; // final is necessary for a and b to be constant expressions.
final byte b=20;
byte c = a + b;
Это не требует приведения.