Don’t mix wrapper types and primitives inside a ternary operator.

Photo by Luku Muffin,

The following method returns one of its parameters depending on the given condition…

Integer select(boolean condition, Integer wrapped, int primitive) {
  if (condition) {
    return wrapped;
  } else {
    return primitive;

…and is invoked as follows:

Integer selected = select(condition, wrapped, primitive);

You might be tempted to replace the whole method by using Java’s ternary operator instead:

Integer selected = condition ? wrapped : primitive;

However, this simple refactoring will result in a NullPointerException if the value of wrapped is null. This is because for some reason, the Java Language Specification demands that if a ternary operator has operands of type Integer and int, then the resulting type must be of type int (and not Integer, like our previous “select” method). As a consequence, even if we assign the result of the ternary expression to an Integer, Java first tries to unbox the wrapped Integer variable, which might trigger a NullPointerException.

To prevent this, you have to manually infer that the primitive value will eventually be boxed anyway:

Integer selected = condition ? wrapped : Integer.valueOf(primitive);

With these parameter types (both Integer), Java uses Integer as the ternary expression’s result type, and doesn’t try to unbox the wrapped variable any longer.