在以下示例中
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。
我一直认为-128属于int类型并且用(int)进行转换应该是多余的。
i3行的错误是
cannot find symbol variable Integer
我尝试使用Java 6 update 29和Java 7 update 1。
编辑:您使用+128而不是-128获得相同的行为。 它确实似乎是一元运算符和二元运算符之间的混淆。
什么是你的编译器? Integer i = -128;这应该编译。
(整数)(-128)怎么样?
wierd,Integer i3 = (Integer) (-128);虽然符合要求。
@ Eng.Fouad,Peter,一元符号(+ - )有从右到左的关联性,加号,减号从左到右。 -128的效果与+128相同,前面的0应固定,即0-128或0 + 128。 (不能测试atm,但我打赌它会)
好问题!我个人希望看到一个JLS引用来解析一元/二元运算符,以及何时将一个转换视为表达式。否则,其他编译器可能不认为它是错误的!
另外,我在IDE中得到的错误是Expression expected,其中Integer是。
@peter只是一个疑问。为什么你需要在java 6和7中进行转换。我认为java 6和7中的自动装箱功能应该照顾它。我没有尝试过代码,所以我可能错了。
你知道Integer与int不一样吗?
@Raedwald,的确如此。
new Integer(-128)怎么样?
当java已经提供自动装箱和解拳的功能时,为什么我们甚至需要进行类型转换?有特殊需要吗?
@neo,在上面的例子中,它不是必需的,但在其他例子中它会产生影响,例如: -128 == -128为true但(Integer) -128 == (Integer) -128为false。一个更复杂的例子是vanillajava.blogspot.co.uk/2010/06/omg-using-triple-cast.html
不知道你是如何测试的,但我对System.out.println(-128 == - 128)是正确的;的System.out.println((整数)( - 128)== - 128);的System.out.println((整数)( - 128)==(整数)( - 128)); //System.out.println((Integer)-128==-128); //不允许或编译
我总觉得int Integer = 10很奇怪;编译。有道理但很奇怪:int Integer = 10;整数i3 =(整数)-128;的System.out.println(I3);
编译器尝试从(Integer)中减去128,而不是将-128转换为Integer。添加()以修复它
Integer i3 = (Integer) -128; // doesn't compile
Integer i3 = (Integer) (-128); // compiles
根据BoltClock在评论中对int的转换按预期工作,因为它是一个保留字,因此不能被解释为标识符,这对我来说是有意义的。
而Bringer128找到了JLS Reference 15.16。
CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus
如您所见,转换为基本类型需要任何UnaryExpression,而转换为引用类型需要UnaryExpressionNotPlusMinus。这些是在JLS 15.15的CastExpression之前定义的。
我认为这是因为int是Java中的关键字,但Integer不是。由于int是一个关键字,因此不能将其用作变量或类的标识符,只留下它作为类型转换的唯一可能性。这就解释了。
@BoltClock在答案中纳入您的评论。
为了使这个答案更加出色,您想将我的链接添加到JLS吗?
@ Bringer128当然。
一个有趣的(对我来说)这个问题的皱纹是我们如何解决C#中的类似问题,它在"括号表达式作为操作数到二元减法运算符"和"强制运算符所在的正确操作数"之间的语法中存在歧义。演员是一个单一的减去表达"。请参阅C#规范的7.7.6节,详细了解我们用来尝试解决这些问题的启发式方法。
像这样的废话使我很高兴我们没有Java中的运算符重载......这可能会在没有时间的情况下变得更加复杂
@BillK你为什么这么说? C#规范并未在7.7.6节中引用运算符重载,因此对它们来说不是问题。
在引入自动装箱之前,这种语法定义非常精细且没有歧义。我认为这是因为Integer对象缓存引起的突然NullPoniterExceptions和不一致的相等性而不是自动装箱的严重缺陷之一。
100为+1和金徽章。 :)
谢谢@Mystical,所有其他的赞成者,以及这个答案的其他贡献者。
我找到了JLS参考。 15.16。
CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus
如您所见,转换为基本类型需要任何UnaryExpression,而转换为引用类型需要UnaryExpressionNotPlusMinus。这些是在JLS 15.15的CastExpression之前定义的。
您需要将强制转换更改为基本类型:
... (int) -128;
或者,您可以将强制转换右侧的表达式更改为非正负一元表达式:
... (Integer) (-128); // Either
... (Integer) 0 - 128; // Or
编译器将-解释为two-arg减号运算符,即它试图从名为Integer的其他数字中减去128,但是范围内没有这样的变量。
这编译:
您可以添加注释(int)为何有所作为。
这是由于自动装箱,不是吗?
它将其解析为Integer 128而未找到变量Integer。您需要将-128包装在括号中:
Integer i3 = (Integer) (-128); // compiles
我已经给所有其他答案+1了,因为他们都是正确的:)
这可能与语法分析有关。请注意
工作得很好。
通常,您不应该转换为Integer类。这涉及一种称为自动装箱的东西,并且可能会在代码中引起一些细微的错误。
做你想做的首选方法是:
Integer i6 = Integer.valueOf(-128)
cast to Integer正是valueOf的合成糖。
是的,但有时合成糖会以微妙的方式失败。由于自动装箱,我有一些很难在大型应用程序中追踪空指针异常。我们将自动装箱视为错误,以便在将来避免头痛。魔术很好,但是当它失败时,头部会受伤。我发现最好是明确并且让自己避免头痛。
NPE是b1tch w / outboxing,是的。像for (int i in Collection) b / c这样的Esp案例NPE处于绝对意想不到的位置。我实际上不使用Integer w / autoboxing,因为缓存范围很小(尽管它可以增加w / XX选项)但是有一个名为IntegerProvider的类(自1.1起)来做同样的事情。使用Map(任何来自java.util)整数 - >任何东西通常都是性能命中,除非它用于琐碎的情况,几乎总是有一个更好的解决方案。
将int转换为Integer永远不会导致任何错误,除非堆溢出。但反过来却不正确。
@bestsss s/synthetic/syntactic
@MattBall,我不太明白,合成糖被广泛使用:eggcorns.lascribe.net/forum/viewtopic.php?id = 4400和合成声音对我来说更好。
问题是-编译器将其视为运算符。
第3行被解释为你试图从括号中的表达式中扣除128并且括号中的表达式不是和int类型的表达式(它将' - '视为' - '运算符)。如果将表达式更改为:
然后编译器将理解' - '是一元减号,表示负整数。
C#编译器具有相同的行为。它提供了一个更好的提示,但为什么它无法编译:
To cast a negative value, you must enclose the value in parentheses