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)