Peter Lawrey
Peter Lawrey

Reputation: 533870

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

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.

Upvotes: 121

Views: 6660

Answers (8)

JefClaes
JefClaes

Reputation: 3373

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

Upvotes: 2

Jens Schauder
Jens Schauder

Reputation: 81988

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.

Upvotes: 150

user545680
user545680

Reputation:

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

Upvotes: 48

Udi Cohen
Udi Cohen

Reputation: 1289

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.

Upvotes: 5

Bohemian
Bohemian

Reputation: 425368

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

Upvotes: 8

Krystian Cybulski
Krystian Cybulski

Reputation: 11118

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)

Upvotes: 8

Brian Roach
Brian Roach

Reputation: 76918

Integer i3 = (Integer) (-128);

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

Upvotes: 6

Barend
Barend

Reputation: 17419

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)

Upvotes: 11

Related Questions