Why does this throw NullPointerException
public static void main(String[] args) throws Exception {
Boolean b = true ? returnsNull() : false; // NPE on this line.
System.out.println(b);
}
public static Boolean returnsNull() {
return null;
}
while this doesn’t
public static void main(String[] args) throws Exception {
Boolean b = true ? null : false;
System.out.println(b); // null
}
?
The solution is by the way to replace false by Boolean.FALSE to avoid null being unboxed to boolean –which isn’t possible. But that isn’t the question. The question is why? Are there any references in JLS which confirms this behaviour, especially of the 2nd case?
The difference is that the explicit type of the
returnsNull()method affects the static typing of the expressions at compile time:See Java Language Specification, section 15.25 Conditional Operator ? :
For E1, the types of the 2nd and 3rd operands are
Booleanandbooleanrespectively, so this clause applies:Since the type of the expression is
boolean, the 2nd operand must be coerced toboolean. The compiler inserts auto-unboxing code to the 2nd operand (return value ofreturnsNull()) to make it typeboolean. This of course causes the NPE from thenullreturned at run-time.For E2, types of the 2nd and 3rd operands are
<special null type>(notBooleanas in E1!) andbooleanrespectively, so no specific typing clause applies (go read ’em!), so the final “otherwise” clause applies:<special null type>(see §4.1)boolean<special null type>(see last item in list of boxing conversions in §5.1.7)BooleanSo the type of the conditional expression is
Booleanand the 3rd operand must be coerced toBoolean. The compiler inserts auto-boxing code for the 3rd operand (false). The 2nd operand doesn’t need the auto-unboxing as inE1, so no auto-unboxing NPE whennullis returned.This question needs a similar type analysis:
Java conditional operator ?: result type