I have this code:
package tests;
import java.util.Hashtable;
public class Tests {
public static void main(String[] args) {
Hashtable
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).
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).
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)