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