Почему int i = 2147483647 + 1;
ОК, но byte b = 127 + 1;
не компилируется?
Почему "int я = 2147483647 + 1;" ОК, но "байт 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;