Любая идея, почему мне нужно передать целочисленный литерал в (int) здесь?

В следующем примере

int i = -128;
Integer i2 = (Integer) i; // compiles

Integer i3 = (Integer) -128; /*** Doesn't compile ***/

Integer i4 = (Integer) (int) -128; // compiles
Integer i4 = -128; // compiles
Integer i5 = (int) -128; // compiles
Integer i6 = (Integer) (-128); // compiles
Integer i7 = (Integer) 0-128; // compiles

Я не могу использовать -128 с (Integer), но я могу использовать (int) -128.

Я всегда считал, что -128 имеет тип int, а литье его с (int) должно быть избыточным.

Ошибка в строке с i3 равна

cannot find symbol variable Integer

Я попробовал это с обновлением версии Java 6 и обновлением Java 7.

EDIT: вы получите то же поведение с +128 вместо -128. Кажется, это путаница между унарными и двоичными операторами.

Ответ 1

Компилятор пытается вычесть 128 из (Integer) вместо того, чтобы отбрасывать -128 в Integer. Добавьте (), чтобы исправить его

Integer i3 = (Integer) -128; // doesn't compile
Integer i3 = (Integer) (-128); // compiles

По словам BoltClock в комментариях, приведение в int работает по назначению, потому что это зарезервированное слово и поэтому не может быть истолковано как идентификатор, что имеет смысл для меня.

И Bringer128 нашел справочник JLS 15.16.

 CastExpression:
    ( PrimitiveType Dimsopt ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus

Как вы можете видеть, для приведения к примитивному типу требуется любое UnaryExpression, тогда как для литья для ссылочного типа требуется UnaryExpressionNotPlusMinus. Они определены непосредственно перед CastExpression в JLS 15.15.

Ответ 2

Я нашел ссылку на JLS. 15.16.

 CastExpression:
    ( PrimitiveType Dimsopt ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus

Как вы можете видеть, для приведения к примитивному типу требуется любое UnaryExpression, тогда как для литья для ссылочного типа требуется UnaryExpressionNotPlusMinus. Они определены непосредственно перед CastExpression в JLS 15.15.

Вам нужно либо сменить бросок на примитивный тип:

... (int) -128;

Или вы можете изменить выражение справа от приведения к унарному выражению без плюса-минуса:

... (Integer) (-128);  // Either
... (Integer) 0 - 128; // Or

Ответ 3

Компилятор интерпретирует - как оператор с двумя аргументами, т.е. пытается вычесть 128 из некоторого другого номера с именем Integer, но в этой области нет такой переменной.

Это компилируется:

Integer i3 = (Integer) (-128)

Ответ 4

Это может быть связано с синтаксисом синтаксиса. Обратите внимание, что

Integer i4 = (Integer) (-128); 

отлично работает.

В общем, вы не должны бросать в класс Integer. Это включает в себя что-то, что называется авто-бокс, и может вызвать некоторые незначительные ошибки в вашем коде. Предпочтительный способ делать то, что вы хотите:

Integer i6 = Integer.valueOf(-128)

Ответ 5

Он анализирует его как Integer <minus operator> 128 и не находит переменную Integer. Вам нужно обернуть -128 в скобках:

Integer i3 = (Integer) (-128);  // compiles

Ответ 6

Integer i3 = (Integer) (-128);

Проблема заключается в -. Компилятор видит это как оператор.

Ответ 7

Строка 3 интерпретируется так же, как вы пытаетесь вычесть 128 из выражения в скобках, а выражение в скобках - это не выражение и выражение типа int (оно относится к оператору '-' как '-'). Если вы измените выражение на:

Integer i3 = (Integer) (-128);

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

Ответ 8

Компилятор С# имеет такое же поведение. Это дает лучший намек, почему он не скомпилирован:

Чтобы указать отрицательное значение, вы должны заключить в круглые скобки значение