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

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.


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