Любая идея, почему мне нужно привести целочисленный литерал в (int) здесь? - PullRequest
122 голосов
/ 26 октября 2011

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

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, обновление 29 и Java7 обновление 1.

РЕДАКТИРОВАТЬ: вы получаете то же поведение с +128 вместо -128.Кажется, это путаница между унарными и бинарными операторами.

Ответы [ 8 ]

151 голосов
/ 26 октября 2011

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

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

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

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

<i><b>CastExpression:
    ( PrimitiveType Dims<sub>opt</sub> ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus</i></b>

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

48 голосов
/ 26 октября 2011

Я нашел ссылку на JLS. 15,16 .

 <i><b>CastExpression:
    ( PrimitiveType Dims<sub>opt</sub> ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus</i></b>

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

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

... (int) -128;

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

... (Integer) (-128);  // Either
... (Integer) 0 - 128; // Or
12 голосов
/ 26 октября 2011

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

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

Integer i3 = (Integer) (-128)
9 голосов
/ 26 октября 2011

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

Integer i3 = (Integer) (-128);  // compiles
9 голосов
/ 26 октября 2011

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

Integer i4 = (Integer) (-128); 

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

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

Integer i6 = Integer.valueOf(-128)
7 голосов
/ 26 октября 2011
Integer i3 = (Integer) (-128);

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

6 голосов
/ 26 октября 2011

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

Integer i3 = (Integer) (-128);

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

3 голосов
/ 02 ноября 2011

Компилятор C # ведет себя так же.Это дает лучшую подсказку, почему он не компилируется, хотя:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...