一尘不染

Boolean.valueOf()有时会产生NullPointerException

java

我有这个代码:

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

我的问题是我不明白为什么 Test 3 可以正常工作(它打印false并且不产生NullPointerException),而 Test
4却
抛出了NullPointerException。正如你可以看到测试 12
nullmodifiedItems.get("item1")是平等的和null

Java 7和8中的行为相同。


阅读 251

收藏
2020-12-03

共1个答案

一尘不染

您必须仔细查看正在调用的重载:

  • Boolean.valueOf(null)正在调用Boolean.valueOf(String)NPE即使提供了null参数,也不会抛出“ even”。
  • Boolean.valueOf(modifiedItems.get("item1"))正在调用Boolean.valueOf(boolean),因为modifiedItems的值类型为Boolean,需要进行拆箱转换。既然modifiedItems.get("item1")null,那就是该值的拆箱-而不是Boolean.valueOf(...)-引发NPE。

确定调用哪个重载的规则非常繁琐,但它们大致如下:

  • 在第一遍中,搜索方法匹配项而不允许装箱/拆箱(也不使用可变Arity方法)。

    • 因为null是一个可接受的值String而不是boolean,在此过程中Boolean.valueOf(null)匹配Boolean.valueOf(String)
    • BooleanBoolean.valueOf(String)或都不可接受的Boolean.valueOf(boolean),因此在此传递中没有方法匹配Boolean.valueOf(modifiedItems.get("item1"))
    • 在第二遍中,搜索方法匹配项,以允许装箱/拆箱(但仍然不是可变arity方法)。

    • Boolean可以将A 拆箱boolean,因此在此过程中Boolean.valueOf(boolean)与匹配Boolean.valueOf(modifiedItems.get("item1"));但是编译器必须插入拆箱转换才能调用它:Boolean.valueOf(modifiedItems.get("item1").booleanValue())

    • (第三遍允许使用可变Arity方法,但此处不相关,因为前两个遍历与这些情况匹配)
2020-12-03