A conditional expression with numeric operands of differing types will perform binary numeric promotion of the operands; when these operands are of reference types, the expression's result may not be of the expected type.


The problem

A conditional expression with numeric second and third operands of differing types may give surprising results.

For example:

Object t = true ? Double.valueOf(0) : Integer.valueOf(0);
System.out.println(t.getClass());  // class java.lang.Double

Object f = false ? Double.valueOf(0) : Integer.valueOf(0);
System.out.println(f.getClass());  // class java.lang.Double !!

Despite the apparent intent to get a Double in one case, and an Integer in the other, the result is a Double in both cases.

This is because the rules in JLS ยง 15.25.2 state that differing numeric types will undergo binary numeric promotion. As such, the latter case is evaluated as:

Object f =
            ? Double.valueOf(0).doubleValue()
            : (double) Integer.valueOf(0).intValue());

To get a different type in the two cases, one can either explicitly cast the operands to a non-boxable type:

Object f = false ? ((Object) Double.valueOf(0)) : ((Object) Integer.valueOf(0));
System.out.println(t.getClass());  // class java.lang.Integer

Or use if/else:

Object f;
if (false) {
  f = Double.valueOf(0);
} else {
  f = Integer.valueOf(0);


Suppress false positives by adding the suppression annotation @SuppressWarnings("ConditionalExpressionNumericPromotion") to the enclosing element.