Search code examples
javabooleanternary-operatorboxingunboxing

NullPointerException throws when I use ternary operator


I have the following return statement:

public Boolean foo(String booleanString){  
    return ("true".equals(booleanString) ? true : ("false".equals(booleanString) ? false : null));
}

when booleanString equal not true and not false I get the NullPointerException.

Is it boxing/unboxing issue?


Solution

  • You guessed it right. For a formal explanation, the answer lies in the JLS:

    If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

    So as you have the primitive true and false in both expressions, the type of your condition expression is boolean.

    When you get into the second expression, in the second case, the null reference is converted into boolean with null.booleanValue();, causing the NPE, so that the expression is equivalent to:

    return Boolean.valueOf(null.booleanValue());
    

    (then the return type of the expression is re-boxed to Boolean, but it's too late as you guessed it).

    For example:

    return ("true".equals(booleanString) ? Boolean.TRUE : ("false".equals(booleanString) ? Boolean.FALSE : null));
    

    does not cause a NPE since the type of the expression is Boolean. This, however,

    return ("true".equals(booleanString) ? true : ("false".equals(booleanString) ? Boolean.FALSE : null));
    

    causes it because again the same rule applies (since the first expression is the primitive boolean type). So it's equivalent to:

    return Boolean.valueOf(("true".equals(booleanString) ? true : ("false".equals(booleanString) ? Boolean.FALSE : null).booleanValue());