Boolean.valueOf()有时会产生NullPointerException

我有这个代码:

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

我的问题是,我不明白为什么testing3工作正常(它打印false ,不会产生NullPointerException )与此同时, testing4将引发NullPointerException 。 正如您在testing12中看到的那样, nullmodifiedItems.get("item1")是equals和null

Java 7和8中的行为是相同的。

你必须仔细看看哪个过载被调用:

  • Boolean.valueOf(null)调用Boolean.valueOf(String) 。 即使提供了null参数,这也不会引发NPE
  • Boolean.valueOf(modifiedItems.get("item1"))正在调用Boolean.valueOf(boolean) ,因为modifiedItems的值是Booleantypes的,需要进行拆箱转换。 由于modifiedItems.get("item1")null ,所以将该值解开,而不是引发NPE的Boolean.valueOf(...)

确定哪个超载被调用的规则是相当多的 ,但它们大致是这样的:

  • 在第一遍中,search方法匹配而不允许装箱/取消装箱(也不是variables方法)。

    • 由于null对于String不是可接受的值,因此Boolean.valueOf(null)Boolean.valueOf(String)匹配。
    • 对于Boolean.valueOf(String)Boolean.valueOf(boolean)Boolean值不是可接受的,因此在此传递中没有方法匹配Boolean.valueOf(modifiedItems.get("item1"))
  • 在第二遍中,search方法匹配,允许装箱/取消装箱(但仍然不是可变的方法)。

    • 一个Boolean可以被解除boolean ,所以在这个booleanBoolean.valueOf(boolean)Boolean.valueOf(modifiedItems.get("item1"))相匹配。 但编译器必须插入一个拆箱转换来调用它: Boolean.valueOf(modifiedItems.get("item1").booleanValue())
  • (第三次通过允许variables方法,但这不是相关的,因为前两个通过匹配这些情况)

由于modifiedItems.get返回一个Boolean不能强制转换为String ),因此将使用的Boolean.valueOf(boolean)Boolean.valueOf(boolean) ,其中Boolean是outboxed到原始boolean 。 一旦返回null ,outboxing将失败并带有NullPointerException

方法签名

方法Boolean.valueOf(...)有两个签名:

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

您的modifiedItems值是Boolean 。 您不能将BooleanString ,因此将select第一个签名

布尔拆箱

在你的声明

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

可以看作是

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

然而, modifiedItems.get("item1")返回null所以你基本上会有

 null.booleanValue() 

这显然导致NullPointerException

由于Andy已经很好地描述了NullPointerException的原因:

这是由于布尔取消拳击:

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

转换成:

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

在运行时,然后抛出NullPointerException如果modifiedItems.get("item1")为空。

现在我想在这里再添加一点,即如果下面的类对它们各自的原语进行NullPointerException如果它们对应的返回对象为null,也可能产生NullPointerExceptionexception。

  1. 字节 – 字节
  2. 字符 – 字符
  3. 浮动 – 浮动
  4. int – 整数
  5. 长隆
  6. 短 – 短
  7. 双 – 双

这里是代码:

  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 

一种理解它的方法是当Boolean.valueOf(null)被调用时,java被精确地告知评估null。

但是,当调用Boolean.valueOf(modifiedItems.get("item1")) ,会通知java从对象types为Boolean的HashTable中获取一个值,但是找不到types为Boolean的types, null)即使它预期布尔值。 抛出了NullPointerExceptionexception,因为这部分java的创build者决定这种情况是程序出错的一个实例,需要程序员的注意。 (有意外的事情发生了。)

在这种情况下,故意声明你打算将null放在那里,而javafind一个对象(null)的缺失引用,而在这个对象被打算find的地方,区别更大。

在这个答案中查看关于NullPointerException的更多信息: https : //stackoverflow.com/a/25721181/4425643