Boolean.valueOf() produces NullPointerException sometimes

You've got to look carefully at which overload is being invoked:

  • Boolean.valueOf(null) is invoking Boolean.valueOf(String). This doesn't throw an NPE even if supplied with a null parameter.
  • Boolean.valueOf(modifiedItems.get("item1")) is invoking Boolean.valueOf(boolean), because modifiedItems's values are of type Boolean, which requires an unboxing conversion. Since modifiedItems.get("item1") is null, it is the unboxing of that value - not the Boolean.valueOf(...) - which throws the NPE.

The rules for determining which overload is invoked are pretty hairy, but they roughly go like this:

  • In a first pass, a method match is searched for without allowing boxing/unboxing (nor variable arity methods).

    • Because null is an acceptable value for a String but not boolean, Boolean.valueOf(null) is matched to Boolean.valueOf(String) in this pass;
    • Boolean isn't an acceptable for either Boolean.valueOf(String) or Boolean.valueOf(boolean), so no method is matched in this pass for Boolean.valueOf(modifiedItems.get("item1")).
  • In a second pass, a method match is searched for, allowing boxing/unboxing (but still not variable arity methods).

    • A Boolean can be unboxed to boolean, so Boolean.valueOf(boolean) is matched for Boolean.valueOf(modifiedItems.get("item1")) in this pass; but an unboxing conversion has to be inserted by the compiler to invoke it: Boolean.valueOf(modifiedItems.get("item1").booleanValue())
  • (There's a third pass allowing for variable arity methods, but that's not relevant here, as the first two passes matched these cases)


Method signature

The method Boolean.valueOf(...) has two signatures:

  1. public static Boolean valueOf(boolean b)
  2. public static Boolean valueOf(String s)

Your modifiedItems value is Boolean. You cannot cast Boolean to String so consequently the first signature will be chosen

Boolean unboxing

In your statement

Boolean.valueOf(modifiedItems.get("item1"))

which can be read as

Boolean.valueOf(modifiedItems.get("item1").booleanValue())   

However, modifiedItems.get("item1") returns null so you'll basically have

null.booleanValue()

which obviously leads to a NullPointerException


Since modifiedItems.get returns a Boolean (which is not castable to a String), the signature that would be used is Boolean.valueOf(boolean), where the Boolean is outboxed to a primitive boolean. Once null is returned there, the outboxing fails with a NullPointerException.