Любая идея, почему мне нужно передать целочисленный литерал в (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
Компилятор С# имеет такое же поведение. Это дает лучший намек, почему он не скомпилирован:
Чтобы указать отрицательное значение, вы должны заключить в круглые скобки значение