Почему "int i = 2147483647 + 1;" ОК, но "байт b = 127 + 1;" не компилируется? - PullRequest
126 голосов
/ 31 июля 2011

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

Ответы [ 4 ]

172 голосов
/ 31 июля 2011

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

35 голосов
/ 31 июля 2011

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

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

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

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

И нет, слово «принуждение» не нуждается в исправлении. При этом он был выбран очень осознанно и правильно. Из ближайшего источника (Википедия): «В большинстве языков слово принуждение используется для обозначения неявного преобразования, либо во время компиляции, либо во время выполнения». и «В информатике преобразование типов, приведение типов и принуждение являются различными способами явного или неявного изменения сущности одного типа данных в другой».

6 голосов
/ 31 июля 2011

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

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

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

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

3 голосов
/ 31 июля 2011

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

(переменная = выражение)

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

Может использоваться сужающее примитивное преобразование, если тип переменной - byte, short или char, а значение константного выражения представлено в типе переменной.


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

byte x = 0;
char c = 0;

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

byte x = (byte)0;
...