What do you think that the following code snippet will print?
Object o = true ? new Integer(1) : new Double(2.0); System.out.println(o);
Yes! It will print:
What? 1.0? But I have assigned an
Integer to my
o variable. Why does it print 1.0? It turns out that there is a subtle little specification section in the JLS’s §15.25, which specifies the ternary operator. Here’s what is applied to the above:
The type of a conditional expression is determined as follows:
- Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
Binary numeric promotion may implicitly perform unboxing conversion! Eek! Who would have expected this? You can get a NullPointerException from auto-unboxing, if one of the operands is
null, the following will fail
Integer i = new Integer(1); if (i.equals(1)) i = null; Double d = new Double(2.0); Object o = true ? i : d; // NullPointerException! System.out.println(o);
Obviously (obviously !?) you can circumvent this problem by casting numeric types to non-numeric types, e.g.
Object o1 = true ? (Object) new Integer(1) : new Double(2.0); System.out.println(o1);
The above will now print
Credits for discovery of this gotcha go to Paul Miner, who has explained this more in detail here on reddit.