Почему "int я = 2147483647 + 1;" ОК, но "байт b = 127 + 1;" не поддается компиляции?

Почему int i = 2147483647 + 1; ОК, но byte b = 127 + 1; не компилируется?

Ответ 1

Константы оцениваются как int, поэтому 2147483647 + 1 переполняется и дает вам новый int, который присваивается int, тогда как 127 + 1 также оценивается как int равно 128, и он не может быть назначен до byte.

Ответ 2

Литерал 127 обозначает значение типа int. Точно так же буквально 1. Сумма этих двух чисел является целым числом 128. Во втором случае проблема заключается в том, что вы назначаете это переменной байта типа. Это не имеет никакого отношения к фактической стоимости выражений. Это связано с тем, что Java не поддерживает принуждения (*). Вы должны добавить тип

byte b = (byte)(127 + 1);

а затем он компилируется.

(*), по крайней мере, не от типа String-to-integer, float-to-Time,... Java поддерживает принуждения, если они в некотором смысле не теряются (Java называет это "расширением" ).

И нет, слово "принуждение" не нуждалось в исправлении. Это было выбрано очень умышленно и правильно. От ближайшего источника к руке (Википедия): "В большинстве языков слово принуждение используется для обозначения неявного преобразования, либо во время компиляции, либо во время выполнения". и "В информатике преобразование типов, приведение типов и принуждение - это различные способы, неявно или явно, изменение объекта одного типа данных на другой.".

Ответ 3

В качестве доказательства для @MByD:

Следующий код компилируется:

byte c = (byte)(127 + 1);

Потому что хотя выражение (127 + 1) является int и выходит за пределы области byte, результат выводится на byte. Это выражение выражает -128.

Ответ 4

JLS3 # 5.2 Преобразование присвоений

(variable = expression)

Кроме того, если выражение является константным выражением (§15.28) типа byte, short, char или int:

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


Без этого предложения мы не сможем писать

byte x = 0;
char c = 0;

Но можем ли мы это сделать? Я так не думаю. В конверсии среди примитивов происходит немало волшебства, нужно быть очень осторожным. Я не собираюсь писать

byte x = (byte)0;