Бинарное сложение выполняет проверку границы типа, тогда как сокращение и приращение не
Я вижу, что код ниже:
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 в байт