Search code examples
javanullpointerexception

NPE:cannot unbox null value


Boolean sortAsc = Objects.nonNull(chooseRequest) ? chooseRequest.getSortAsc() : false;

This code will throw NPE exception, why?

chooseRequest is a DTO and chooseRequest.getSortAsc() will return null

but this one is ok

Boolean sortAsc = Objects.nonNull(chooseRequest) ? null : false;

I cannot understand, JVM is 11


Solution

  • When you have the expression

    Objects.nonNull(chooseRequest)
        ? chooseRequest.getSortAsc()
        : false
    

    and the return type of chooseRequest.getSortAsc() is defined as Boolean, then the "result" of this (boolean) conditional expression will be a boolean (the primitive type), as indicated in the table Table 15.25-B. Conditional expression type (Primitive 3rd operand, Part II):

    Table 15.25-B. Conditional expression type (Primitive 3rd operand, Part II)

    3rd → [...] boolean
    2nd ↓
    [...]
    Boolean boolean

    When chooseRequest.getSortAsc() is returning null, you will get a NullPointerException because it tries to call the java.lang.Boolean.booleanValue() method on null to convert the Boolean value to a boolean value.

    However, when you have the expression

    Objects.nonNull(chooseRequest)
        ? null
        : false
    

    then the "result" of this (reference) condition expression will be a Boolean (the wrapper class):

    Table 15.25-B. Conditional expression type (Primitive 3rd operand, Part II)

    3rd → [...] boolean
    2nd ↓
    [...]
    null lub(null,Boolean)

    (for a definition of lub() see 4.10.4. Least Upper Bound. Also see What is lub(null, Double)?)

    No NullPointerException will be thrown here because no method is called on null.

    Overall, the NullPointerException is not coming from calling the getSortAsc() method on null as you might suspect, it's coming from a conversion of null to a boolean value. Interestingly, if you change your variable from Boolean sortAsc to boolean sortAsc, your second code block will throw a NullPointerException as well, since it tries to call java.lang.Boolean.booleanValue() on the returned null value (assuming Objects.nonNull(chooseRequest) returned true at that time).