Any idea why I need to cast an integer literal to (int) here?

在下面的示例中

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

我不能用 (Integer)-128但我可以用 (int) -128

我一直认为 -128int类型和铸造它与 (int)应该是多余的。

The error on the line with i3 is

cannot find symbol variable Integer

我在 Java6更新29和 Java7更新1中尝试了这种方法。

编辑: 使用 +128而不是 -128得到相同的行为。这似乎是一元运算符和二元运算符之间的混淆。

6247 次浏览

编译器将 -解释为两个 arg 减号操作符,也就是说,它试图从另一个名为 Integer的数字中减去128,但在作用域中没有这样的变量。

结果显示:

Integer i3 = (Integer) (-128)

编译器试图从 (Integer)中减去 128,而不是将 -128强制转换为 Integer

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

根据 BoltClock 在评论中的说明,对 int的强制转换可以正常工作,因为它是一个保留字,因此不能被解释为一个标识符,这对我来说是有意义的。

Bringer 128找到了 JLS 参考 15.16

 CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus

如您所见,转换为基元类型需要任何 UnaryExpression,而转换为引用类型则需要 UnaryExpressionNotPlusMinus。这些是在 JLS 15.15的 CastExpression 之前定义的。

Integer i3 = (Integer) (-128);

问题是 -编译器把它看作一个操作符。

这可能与语法分析有关

Integer i4 = (Integer) (-128);

没问题。

一般情况下,不应强制转换为 Integer 类。这涉及到所谓的自动装箱,可能会导致代码中出现一些细微的错误。 The prefered method of doing what you want is:

Integer i6 = Integer.valueOf(-128)

It's parsing it as Integer <minus operator> 128 and not finding the variable Integer. You'll need to wrap the -128 in brackets:

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

第3行的解释就像是你试图从括号中的表达式中扣除128,而括号中的表达式是 not 和 int 类型的表达式(它将’-’作为’-’运算符对待)。如果将表达式更改为:

Integer i3 = (Integer) (-128);

then the compiler will understand the '-' is the unary minus that indicates a negative integer.

我找到了 JLS 的参考资料 15.16

 CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus

如您所见,转换为基元类型需要任何 UnaryExpression,而转换为引用类型则需要 UnaryExpressionNotPlusMinus。这些是在 JLS 15.15的 CastExpression 之前定义的。

您需要将强制转换更改为基元类型:

... (int) -128;

或者可以将强制转换右侧的表达式更改为非加减一元表达式:

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

C # 编译器也有同样的行为,不过它给出了一个更好的提示,为什么它无法编译:

若要强制转换负值,必须将该值放在括号中