Here’s the relevant quote from the spec (§15.25.2):
Boolean conditional expressions are standalone expressions (§15.2).
The type of a boolean conditional expression is determined as follows:
If the second and third operands are both of type
Boolean
, the conditional expression has typeBoolean
.Otherwise, the conditional expression has type
boolean
.
Therefore, the overall expression’s type is considered to be boolean
, and the Boolean
value is autounboxed, causing a NullPointerException
.
As mentioned in the comments, why doesn’t the following raise an exception?
return val == null ? null : "true".equalsIgnoreCase(val);
Well, the above excerpt from the spec specifically only applies to boolean conditional expressions, which are specified here (§15.25):
If both the second and the third operand expressions are boolean expressions, the conditional expression is a boolean conditional expression.
For the purpose of classifying a conditional, the following expressions are boolean expressions:
An expression of a standalone form (§15.2) that has type
boolean
orBoolean
.A parenthesized
boolean
expression (§15.8.5).A class instance creation expression (§15.9) for class
Boolean
.A method invocation expression (§15.12) for which the chosen most specific method (§15.12.2.5) has return type
boolean
orBoolean
.
(Note that, for a generic method, this is the type before instantiating the method’s type arguments.)A
boolean
conditional expression.
Since null
is not a boolean expression, the overall conditional expression is not a boolean conditional expression. Referring to Table 15.2 (later in the same section), we can see that such an expression is considered to have a Boolean
type, so no unboxing occurs, and no exception is raised.