Почему я не могу добавить два байта и получить int, и я могу добавить два последних байта, чтобы получить байт?

public class Java{
    public static void main(String[] args){
        final byte x = 1;
        final byte y = 2;
        byte z = x + y;//ok
        System.out.println(z);

        byte a = 1;
        byte b = 2;
        byte c = a + b; //Compiler error
        System.out.println(c);
    }
}

Если результат выражения, включающего в себя что-либо, имеющее значение int-size или less, всегда является int, даже если сумма двух байтов соответствует байту.

Почему это происходит, когда мы добавляем два последних байта, которые вписываются в байты? Ошибка компилятора отсутствует.

Ответ 1

Из преобразования JLS 5.2 Assignment Conversion

Кроме того, , если выражение является константным выражением (§15.28) типа byte, short, char или int:  - Сужение примитивного преобразования может быть использовано, если тип    переменная является байтом, коротким или char, а значение константы    выражение представляется в типе переменной.

Короче говоря, значение выражения (которое известно во время компиляции, поскольку оно является постоянным выражением) представляется в типе переменной, байт.

Рассмотрим ваше выражение

 final byte x = 1;
 final byte y = 2;
 byte z = x + y;//This is constant expression and value is known at compile time

Так как суммирование вписывается в байты, оно не вызывает ошибки компиляции.

Теперь, если вы делаете

final byte x = 100;
final byte y = 100;
byte z = x + y;// Compilation error it no longer fits in byte

Ответ 2

byte z = x + y;  // x and y are declared final

Здесь, поскольку x и y объявлены final, поэтому значение выражения на RHS известно во время компиляции, которое фиксировано в (1 + 2 = 3) и не может меняться. Таким образом, вам не нужно явно указывать его

byte c = a + b;   // a and b are not declared final

В то время как в этом случае значение a и b не объявляется окончательным. Таким образом, значение выражения неизвестно во время компиляции, а оценивается во время выполнения. Итак, вам нужно сделать явный листинг.


Однако даже в первом коде, если значение a + b выходит за пределы диапазона -128 to 127, оно не скомпилируется.

final byte b = 121;
final byte a = 120;
byte x = a + b;  // This won't compile, as `241` is outside the range of `byte`

final byte b1 = 12;
final byte a1 = 12;
byte x1 = a1 + b1;  // Will Compile. byte can accommodate `24`