Boolean.valueOf() produces NullPointerException sometimes
Solution 1:
You've got to look carefully at which overload is being invoked:
-
Boolean.valueOf(null)
is invokingBoolean.valueOf(String)
. This doesn't throw anNPE
even if supplied with a null parameter. -
Boolean.valueOf(modifiedItems.get("item1"))
is invokingBoolean.valueOf(boolean)
, becausemodifiedItems
's values are of typeBoolean
, which requires an unboxing conversion. SincemodifiedItems.get("item1")
isnull
, it is the unboxing of that value - not theBoolean.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 aString
but notboolean
,Boolean.valueOf(null)
is matched toBoolean.valueOf(String)
in this pass; -
Boolean
isn't an acceptable for eitherBoolean.valueOf(String)
orBoolean.valueOf(boolean)
, so no method is matched in this pass forBoolean.valueOf(modifiedItems.get("item1"))
.
- Because
-
In a second pass, a method match is searched for, allowing boxing/unboxing (but still not variable arity methods).
- A
Boolean
can be unboxed toboolean
, soBoolean.valueOf(boolean)
is matched forBoolean.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())
- A
(There's a third pass allowing for variable arity methods, but that's not relevant here, as the first two passes matched these cases)
Solution 2:
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
.
Solution 3:
Method signature
The method Boolean.valueOf(...)
has two signatures:
public static Boolean valueOf(boolean b)
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
Solution 4:
As Andy already very well described the reason of NullPointerException
:
which is due to Boolean un-boxing:
Boolean.valueOf(modifiedItems.get("item1"))
get converted into:
Boolean.valueOf(modifiedItems.get("item1").booleanValue())
at runtime and then it throw NullPointerException
if modifiedItems.get("item1")
is null.
Now I would like to add one more point here that un-boxing of the following classes to their respective primitives can also produce NullPointerException
exception if their corresponding returned objects are null.
- byte - Byte
- char - Character
- float - Float
- int - Integer
- long - Long
- short - Short
- double - Double
Here is the code:
Hashtable<String, Boolean> modifiedItems1 = new Hashtable<String, Boolean>();
System.out.println(Boolean.valueOf(modifiedItems1.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Byte> modifiedItems2 = new Hashtable<String, Byte>();
System.out.println(Byte.valueOf(modifiedItems2.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Character> modifiedItems3 = new Hashtable<String, Character>();
System.out.println(Character.valueOf(modifiedItems3.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Float> modifiedItems4 = new Hashtable<String, Float>();
System.out.println(Float.valueOf(modifiedItems4.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Integer> modifiedItems5 = new Hashtable<String, Integer>();
System.out.println(Integer.valueOf(modifiedItems5.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Long> modifiedItems6 = new Hashtable<String, Long>();
System.out.println(Long.valueOf(modifiedItems6.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Short> modifiedItems7 = new Hashtable<String, Short>();
System.out.println(Short.valueOf(modifiedItems7.get("item1")));//Exception in thread "main" java.lang.NullPointerException
Hashtable<String, Double> modifiedItems8 = new Hashtable<String, Double>();
System.out.println(Double.valueOf(modifiedItems8.get("item1")));//Exception in thread "main" java.lang.NullPointerException