Auto-unboxing need of ternary if-else

Viewed 822

This piece of code works fine :-

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

But this throws null-pointer exception, while Eclipse warning that there is need for auto-unboxing :-

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

Why is that so, can somebody guide please?

4 Answers

The type of the ternary conditional expression

1 <= 3 ? nullInt : -1

is int (the JLS contains several tables that describe the type of the ternary conditional operator depending on the types of the 2nd and 3rd operands).

Therefore, when it tries to unbox nullInt to an int, a NullPointerException is thrown.

In order to get the behavior of your if-else snippet, you need to write:

1 <= 3 ? nullInt : Integer.valueOf(-1)

Now the type of the expression will be Integer, so no unboxing will take place.

I'm pretty sure that arguments to ternary operator need to be of this same type. Since you using -1 and some constant nullint compiler tries to unbox nullint to get value. And then autobox it to store in secondNull variable.

This is because when the two operands for the conditional operator ? : are a primitive type and its boxed reference type, an unboxing conversion is done (JLS §15.25.2):

The type of a numeric conditional expression is determined as follows:

  • ...
  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

In general, replacing an if statement with a ? : expression does not always preserve the meaning of the code, because the ? : expression itself needs to have a compile-time type. That means when the types of the two operands are different, a conversion must be done to one or both so that the result has a consistent compile-time type.

This one worked (in Java 1.8):

Integer secondNull = 1 <= 3 ? null : -1;
Related