Java 知道我为什么需要在这里将整数文本转换为(int)吗?

Java 知道我为什么需要在这里将整数文本转换为(int)吗?,java,syntax,casting,Java,Syntax,Casting,在下面的示例中 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 = (Inte

在下面的示例中

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
,但我可以强制转换
(int)-128

我一直认为
-128
属于
int
类型,用
(int)
强制转换它应该是多余的

带有
i3
的行上的错误为

cannot find symbol variable Integer
我在Java6Update29和Java7Update1中尝试了这一点


编辑:您可以使用
+128
而不是
-128
获得相同的行为。一元运算符和二元运算符之间似乎存在混淆。

编译器将
-
解释为两个arg减号运算符,即它试图从另一个名为
整数的数中减去128,但范围中没有此类变量

这包括:

Integer i3 = (Integer) (-128)

编译器尝试从
(整数)
中减去
128
,而不是将
-128
转换为
整数。添加
()
以修复它

Integer i3 = (Integer) -128; // doesn't compile
Integer i3 = (Integer) (-128); // compiles
根据BoltClock在评论中的说法,对
int
的转换符合预期,因为它是一个保留字,因此不能解释为标识符,这对我来说是有意义的

Bringer128找到了JLS参考

CastExpression: (原语类型Dimsopt)一元表达式 (ReferenceType)一元表达式NotPlusMinus 如您所见,强制转换为基元类型需要任何
unarysexpression
,而强制转换为引用类型需要
unarysexpressionnotplusminus
。这些是在的CastExpression之前定义的


问题在于编译器将其视为运算符。

这可能与语法分析有关。注意

Integer i4 = (Integer) (-128); 
很好用

通常,不应强制转换为Integer类。这涉及到一种称为自动装箱(auto-boxing)的方法,可能会导致代码中出现一些微妙的错误。 做你想做的事情的首选方法是:

Integer i6 = Integer.valueOf(-128)

它将其解析为
Integer 128
,而没有找到变量
Integer
。您需要将
-128
括在括号中:

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

第3行被解释为试图从括号中的表达式中扣除128,而括号中的表达式不是int类型的表达式(它将“-”视为“-”运算符)。如果将表达式更改为:

Integer i3 = (Integer) (-128);

然后编译器将理解“-”是表示负整数的一元减号。

我找到了JLS引用

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

... (Integer) (-128);  // Either
... (Integer) 0 - 128; // Or
C#编译器也有同样的行为。它给出了一个更好的提示,说明了它为什么无法编译:

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


你的编译器是什么<代码>整数i=-128这应该编译,尽管.wierd,
Integer i3=(Integer)(-128)
1.@Eng.Fouad,Peter,一元符号(+-)具有从右到左的关联性,加号和减号具有从左到右的关联性。-128的效果与+128相同,将0放在前面应该是固定的,即0-128或0+128。(不能测试自动取款机,但我打赌它会)好问题!我个人希望看到一元/二元运算符解析的JLS参考,以及将强制转换作为表达式处理的情况。否则,其他编译器可能不认为它是错误的!另外,仅供参考,我在IDE中得到的错误是
Expression expected
,其中
Integer
是。cast to Integer正是value of的合成糖。是的,但有时合成糖会以微妙的方式失败。由于自动装箱,我在大型应用程序中遇到了一些难以跟踪的空指针异常。为了避免将来的头痛,我们甚至将自动装箱视为错误。魔法是好的,但当它失败时,头部会受伤。我发现最好是直言不讳,省去你自己的头疼。NPE是一种不带拳击的游戏,没错。Esp案例,如
for(集合中的int i)
b/c NPE处于绝对意外的位置。实际上,我没有使用Integer w/autoboxing,因为缓存范围很小(尽管可以通过w/XX选项增加),但是有一个名为IntegerProvider的类(从1.1开始)来做同样的事情。使用Map(any from java.util)Integer->Anything通常会影响性能,除非它用于琐碎的情况,而且几乎总是有更好的解决方案。将int转换为Integer永远不会导致任何错误,可能除了堆溢出。但事实并非如此。@MattBall,我不太明白,合成糖被广泛使用:而且对我来说,合成糖听起来更好。你可以添加一条注释,说明为什么
(int)
会产生不同。这是因为自动装箱,否?我给所有其他答案加了+1,因为它们也都是正确的:)我想这是因为
int
在Java中是一个关键字,但
Integer
不是。由于
int
是一个关键字,因此不能将其用作变量或类的标识符,只剩下类型转换的可能性。这就解释了。@BoltClock在答案中加入了你的评论。为了让这个答案更精彩,你想把我的链接添加到JLS吗?这个问题上(对我来说)一个有趣的问题是我们如何解决C#中的类似问题,它在语法上也有歧义“括号表达式作为二进制减法运算符的操作数”和“强制转换运算符,其中强制转换的右操作数是一元减法表达式“。请参阅C#规范第7.7.6节,以了解我们在解决amgiguity问题时尝试使用的启发式方法的详细说明。@BillK你为什么这么说?C#规范在第7.7.6节中没有提到运算符重载,因此这对他们来说不是问题。
Integer i3 = (Integer) (-128);
CastExpression: ( PrimitiveType Dimsopt ) UnaryExpression ( ReferenceType ) UnaryExpressionNotPlusMinus
... (int) -128;
... (Integer) (-128);  // Either
... (Integer) 0 - 128; // Or