Boolean.valueOf() produces NullPointerException sometimes

JavaNullpointerexceptionBoolean

Java Problem Overview


I have this code:

package tests;

import java.util.Hashtable;

public class Tests {

    public static void main(String[] args) {

	    Hashtable<String, Boolean> modifiedItems = new Hashtable<String, Boolean>();
	
	    System.out.println("TEST 1");
	    System.out.println(modifiedItems.get("item1")); // Prints null
	    System.out.println("TEST 2");
	    System.out.println(modifiedItems.get("item1") == null); // Prints true
	    System.out.println("TEST 3");
	    System.out.println(Boolean.valueOf(null)); // Prints false
	    System.out.println("TEST 4");
	    System.out.println(Boolean.valueOf(modifiedItems.get("item1"))); // Produces NullPointerException
	    System.out.println("FINISHED!"); // Never executed
    }
}

My problem is that I don't understand why Test 3 works fine (it prints false and doesn't produce NullPointerException) meanwhile Test 4 throws a NullPointerException. As you can see in tests 1 and 2, null and modifiedItems.get("item1") are equals and null.

The behavior is the same in Java 7 and 8.

Java Solutions


Solution 1 - Java

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)

Solution 2 - Java

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 - Java

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

Solution 4 - Java

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.

  1. byte - Byte
  2. char - Character
  3. float - Float
  4. int - Integer
  5. long - Long
  6. short - Short
  7. 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

Solution 5 - Java

A way to understand it is when Boolean.valueOf(null) is invoked, java is precisely being told to evaluate null.

However, when Boolean.valueOf(modifiedItems.get("item1")) is invoked, java is told to obtain a value from the HashTable of object type Boolean, but it doesn't find the type Boolean it finds a dead end instead (null) even though it expected Boolean. The NullPointerException exception is thrown because the creators of this part of java decided this situation is an instance of something in the program going wrong that needs the programmer's attention. (Something unintended happened.)

In this case it is more the difference between deliberately declaring that you intended the null to be there, and java finding a missing reference to an object (null) where an object was intended to be found.

See more information about NullPointerException in this answer: https://stackoverflow.com/a/25721181/4425643

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDavid EView Question on Stackoverflow
Solution 1 - JavaAndy TurnerView Answer on Stackoverflow
Solution 2 - JavaMureinikView Answer on Stackoverflow
Solution 3 - JavaAl-unView Answer on Stackoverflow
Solution 4 - JavaMohit TyagiView Answer on Stackoverflow
Solution 5 - JavaCausingUnderflowsEverywhereView Answer on Stackoverflow