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

JavaSyntaxCasting

Java Problem Overview


In the following example

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

I can't cast -128 with (Integer) but I can cast (int) -128.

I always thought -128 was of int type and casting it with (int) should be redundant.

The error on the line with i3 is

cannot find symbol variable Integer

I tried this with Java 6 update 29 and Java 7 update 1.

EDIT: You get the same behavior with +128 instead of -128. It does appear to be confusion between unary and binary operators.

Java Solutions


Solution 1 - Java

The compiler tries to subtract 128 from (Integer) instead of casting -128 to Integer. Add () to fix it

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

According to BoltClock in the comments the cast to int works as intended, because it is a reserved word and therefore can't be interpreted as an identifier, which makes sense to me.

And Bringer128 found the JLS Reference 15.16.

 CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus

As you can see, casting to a primitive type requires any UnaryExpression, whereas casting to a reference type requires a UnaryExpressionNotPlusMinus. These are defined just before the CastExpression at JLS 15.15.

Solution 2 - Java

I found the JLS reference. 15.16.

 CastExpression:
( PrimitiveType Dimsopt ) UnaryExpression
( ReferenceType ) UnaryExpressionNotPlusMinus

As you can see, casting to a primitive type requires any UnaryExpression, whereas casting to a reference type requires a UnaryExpressionNotPlusMinus. These are defined just before the CastExpression at JLS 15.15.

You need to either change the cast to a primitive type:

... (int) -128;

Or you can change the expression to the right of the cast to a non-plus-minus unary expression:

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

Solution 3 - Java

The compiler interprets the - as the two-arg minus operator, i.e. it's trying to subtract 128 from some other number named Integer, but there's no such variable in scope.

This compiles:

Integer i3 = (Integer) (-128)

Solution 4 - Java

This may have to do with syntax parsing. Notice that

Integer i4 = (Integer) (-128); 

works just fine.

In general, you should not cast to Integer class. This involves something called auto-boxing, and can cause some subtle errors in your code. The prefered method of doing what you want is:

Integer i6 = Integer.valueOf(-128)

Solution 5 - Java

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

Solution 6 - Java

Integer i3 = (Integer) (-128);

The problem is the - The compiler sees it as an operator.

Solution 7 - Java

Line 3 is interpreted like you're trying to deduct 128 from the expression in the parenthesis and the expression in the parenthesis is not and expression of type int (It treats the '-' as a '-' operator). If you change the expression to:

Integer i3 = (Integer) (-128);

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

Solution 8 - Java

The C# compiler has the same behaviour. It gives a better hint why it fails to compile though:

>To cast a negative value, you must enclose the value in parentheses

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPeter LawreyView Question on Stackoverflow
Solution 1 - JavaJens SchauderView Answer on Stackoverflow
Solution 2 - JavaBringer128View Answer on Stackoverflow
Solution 3 - JavaBarendView Answer on Stackoverflow
Solution 4 - JavaKrystian CybulskiView Answer on Stackoverflow
Solution 5 - JavaBohemianView Answer on Stackoverflow
Solution 6 - JavaBrian RoachView Answer on Stackoverflow
Solution 7 - JavaUdi CohenView Answer on Stackoverflow
Solution 8 - JavaJefClaesView Answer on Stackoverflow