Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwanted NullPointerException in ternary operator - Why? [duplicate]

While executing the following code, I am getting a NullPointerException at line:

value = condition ? getDouble() : 1.0;

In earlier lines when I use null instead of getDouble() everything works and this is strange.

public class Test {
    static Double getDouble() {
        return null;
    }

    public static void main(String[] args) {
        boolean condition = true;
        Double value;

        value = condition ? null : 1.0;         //works fine
        System.out.println(value);              //prints null

        value = condition ? getDouble() : 1.0;  //throws NPE
        System.out.println(value);
    }
}

Can someone help me understand this behavior?

like image 712
Sachin Sachdeva Avatar asked Sep 03 '18 09:09

Sachin Sachdeva


2 Answers

When you write

value = condition ? null : 1.0;

the type of condition ? null : 1.0 must be a reference type, so the type is Double, which can hold the value null.

When you write

value = condition ? getDouble() : 1.0;

and getDouble() returns null, it's equivalent to writing:

value = condition ? ((Double) null) : 1.0;

In this case the compiler sees a Double and a double as the 2nd and 3rd arguments of the ternary conditional operator, and decides that type of the expression should be double. Therefore it unboxes the null to double, getting NullPointerException.

The type of the conditional ternary operator is determined by some tables in JLS 15.25.

If the 2nd and 3rd operands are null and double, the conditional expression type is the least upper bound of Double and null, which is Double.

If the 2nd and 3rd operands are Double and double, the conditional expression type is double.

like image 200
Eran Avatar answered Nov 09 '22 02:11

Eran


See #jls-15.25:

enter image description here

If the 2nd operand is Double, while the 3rd operand is double, the result:

getCount() == 1 ? getDouble() : 1.0

will be a double.

And when you try to convert a Double null(returned by getDouble()) to double, NPE will be thrown.

like image 26
xingbin Avatar answered Nov 09 '22 03:11

xingbin