知道为什么我需要将整数文字转换为(int)吗?

Pet*_*rey 122 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 = (Integer) (-128); // compiles
Integer i7 = (Integer) 0-128; // compiles
Run Code Online (Sandbox Code Playgroud)

我不能施展-128,(Integer)但我可以施展(int) -128.

我一直认为它-128int类型,并且它(int)应该是多余的.

行上的错误i3

cannot find symbol variable Integer
Run Code Online (Sandbox Code Playgroud)

我尝试使用Java 6 update 29和Java 7 update 1.

编辑:您获得相同的行为,+128而不是-128.它确实似乎是一元运算符和二元运算符之间的混淆.

Jen*_*der 151

编译器试图减去128(Integer)代替铸造-128Integer.添加()修复它

Integer i3 = (Integer) -128; // doesn't compile
Integer i3 = (Integer) (-128); // compiles
Run Code Online (Sandbox Code Playgroud)

根据BoltClock的评论,演员 int按预期工作,因为它是一个保留字,因此不能被解释为标识符,这对我来说很有意义.

而Bringer128找到了JLS Reference 15.16.

 CastExpression:
    ( PrimitiveType Dimsopt ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus

如您所见,转换为基本类型需要any UnaryExpression,而转换为引用类型则需要a UnaryExpressionNotPlusMinus.这些是在JLS 15.15的CastExpression之前定义的.

  • 我认为这是因为`int`是Java中的关键字,但是`Integer`不是.由于`int`是一个关键字,你不能将它用作变量或类的标识符,只留下它作为类型转换的唯一可能性.这就解释了. (31认同)
  • 为了使这个答案更加出色,您想将我的链接添加到JLS吗? (3认同)
  • 一个有趣的(对我来说)这个问题的皱纹是我们如何解决C#中的类似问题,它在"括号表达式作为操作数到二元减法运算符"和"强制运算符所在的正确操作数"之间的语法中存在歧义.演员是一个单一的减去表达".请参阅C#规范的7.7.6节,详细了解我们用来尝试解决这些问题的启发式方法. (3认同)

Bri*_*128 48

我找到了JLS参考.15.16.

 CastExpression:
    ( PrimitiveType Dimsopt ) UnaryExpression
    ( ReferenceType ) UnaryExpressionNotPlusMinus

如您所见,转换为基本类型需要any UnaryExpression,而转换为引用类型则需要a UnaryExpressionNotPlusMinus.这些是在JLS 15.15的CastExpression之前定义的.

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

... (int) -128;
Run Code Online (Sandbox Code Playgroud)

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

... (Integer) (-128);  // Either
... (Integer) 0 - 128; // Or
Run Code Online (Sandbox Code Playgroud)


Bar*_*end 12

编译器解释-为两个arg减运算符,即它试图从一个其他命名的数字中减去128 Integer,但是范围内没有这样的变量.

这编译:

Integer i3 = (Integer) (-128)
Run Code Online (Sandbox Code Playgroud)


Kry*_*ski 9

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

Integer i4 = (Integer) (-128); 
Run Code Online (Sandbox Code Playgroud)

工作得很好.

通常,您不应该转换为Integer类.这涉及一种称为自动装箱的东西,并且可能会在代码中引起一些细微的错误.做你想做的首选方法是:

Integer i6 = Integer.valueOf(-128)
Run Code Online (Sandbox Code Playgroud)

  • 是的,但有时合成糖会以微妙的方式失败.由于自动装箱,我有一些很难在大型应用程序中追踪空指针异常.我们将自动装箱视为错误,以便在将来避免头痛.魔法很好,但是当它失败时,头部会受伤.我发现最好是明确并且让自己避免头痛. (4认同)

Boh*_*ian 9

它正在解析它Integer <minus operator> 128而不是找到变量Integer.你需要-128用括号括起来:

Integer i3 = (Integer) (-128);  // compiles
Run Code Online (Sandbox Code Playgroud)


Bri*_*ach 7

Integer i3 = (Integer) (-128);
Run Code Online (Sandbox Code Playgroud)

问题是-编译器将其视为运算符.


Udi*_*hen 6

第3行被解释为你试图从括号中的表达式中扣除128并且括号中的表达式不是和int类型的表达式(它将' - '视为' - '运算符).如果将表达式更改为:

Integer i3 = (Integer) (-128);
Run Code Online (Sandbox Code Playgroud)

然后编译器将理解' - '是一元减号,表示负整数.