Ternary operator puzzle

February 23rd 2013 by Samuel Rossille

ternary-operator-puzzle This is from a real life case, and a really hard one...

In the Java program below, the min1 method is the good implementation of the need and is here to show what we are trying to do. And the min2 method is the trash code that gave me the headache.

So what happens if you execute this program ? And what's harder to find out, why ?

public class Puzzle {
    private static Integer min1(Integer i1, Integer i2) {
        if(i1 == null) {
            return i2;
        }
        else {
            if(i2 == null) {
                return i1;
            }
            else {
                return Math.min(i1, i2);
            }
        }
    }

    private static Integer min2(Integer i1, Integer i2) {
        return i1 == null ? i2 : (i2 == null ? i1 : Math.min(i1, i2));
    }

    public static void main(String[] args) {
        System.out.println(min1(null, null));
        System.out.println(min2(null, null));
    }
}

So what do you think?

"><style type="text/css"> .tip { display: none; } </style> <a href="javascript:hint()">Give me a hint</a> <div class="tip"> This is what happens: <pre>null Exception in thread "main" java.lang.NullPointerException at Puzzle.min2(Puzzle.java:17) at Puzzle.main(Puzzle.java:22) </pre> But why? [Give me a hint](javascript:hint\(2\)) Compile time overload resolution states that the `Math.min` method used in the expression is ```java public static int min(int a, int b)

So what?)

What is the type of (i2 == null ? i1 : Math.min(i1, i2))?

Good question, what is the type?)

Quote from the The Java Language Specification:

[...] The type of a conditional expression is determined as follows:

In our case, the second operand's type is Integer and the third operand's type is int

I want to see the solution!)

First bullet point is not applicable because types are not the same.

Second bullet point is applicable if the int type as T. Hence, the type of (i2 == null ? i1 : Math.min(i1, i2)) is int. The same mechanism defines the type of the whole i1 == null ? i2 : (i2 == null ? i1 : Math.min(i1, i2)) expression: int As specified, the first expression of the first ternary operator is chosen, evaluated, and the result is unboxed to meet the type decided for the ternary operator. And here comes the NPE while unboxing null. There would be a boxing after that to return an Integer, but we don't get the chance to reach this point.

Not too easy, huh? Please share if you like.