Бинарное сложение выполняет проверку границы типа, тогда как сокращение и приращение не

Я вижу, что код ниже:

byte b = 127;
b = b + 1;
b = b + 1;
System.out.println(b);

приводит к проверке границ во время выполнения, и первое добавление выводит b из диапазона, что приводит к следующей ошибке -

Main.java:11: ошибка: несовместимые типы: возможное преобразование с потерями из int в байт b=b+1; Main.java:12: ошибка: несовместимые типы: возможное преобразование с потерями из int в байт b = b + 1;

Однако, когда я использую сокращение или приращение, как:

byte b = 127;
b += 1;
b++;
System.out.println(b);

мы находим, что значение байта "оборачивается", давая выход

-127

Почему эта аномалия? Что на самом деле мешает добавлению обернуться (как это делает C) или приращению / сокращению выполнить проверку границ?

2 ответа

Решение

Почему эта аномалия?

Когда вы добавляете byte плюс int Вы получаете int поэтому, когда вы назначаете его byte это жалуется. Однако, когда вы делаете

b += 1;

В этой операции есть неявное приведение, которое неочевидно, но находится в JLS. Более понятный пример

char ch = '0';
ch /= 0.9; // << an implicit cast occurs here.
System.out.println(ch); // 5

Точно так же, когда вы делаете

b++;

для компиляции необходимо допустить переполнение.

Короче говоря, разница в том, что

b = b + 1;

имеет два оператора вместо одного, и это приводит к предупреждению о возможном переполнении.

Примечание: это не относится к int или же long типы, как вы можете сделать

int i = Integer.MAX_VALUE;
i = i + 1; // no warning as int is not widened to long
long l = Long.MAX_VALUE;
l = l + 1; // no warning as long is the widest type.

Даже если Java 10 может иметь Long2 для 128-битных целых чисел (и это может) long все еще не будет расширен.

Для байта Минимальное значение -128 (-2^7) Максимальное значение 127, таким образом, если большее значение преобразуется в int

byte b  = (int) b + 1

Таким образом, не может преобразовать большой int в байт

Другие вопросы по тегам