NPE:cannot unbox null value

63 views Asked by At
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

1

There are 1 answers

1
Progman On BEST ANSWER

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).