Boolean.valueOf()有时会产生NullPointerException

Dav*_*d E 113 java boolean 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
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我不明白为什么测试3工作正常(它打印false并且不产生NullPointerException)同时测试4抛出一个NullPointerException.正如你在测试12中看到的那样,null并且modifiedItems.get("item1")是等于和null.

Java 7和8中的行为相同.

And*_*ner 173

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

  • Boolean.valueOf(null)正在调用Boolean.valueOf(String).NPE如果提供null参数,则不会抛出偶数.
  • Boolean.valueOf(modifiedItems.get("item1"))正在调用Boolean.valueOf(boolean),因为它modifiedItems的值是类型Boolean,需要取消装箱转换.由于modifiedItems.get("item1")IS null,它是价值的拆箱-不是Boolean.valueOf(...)-它抛出NPE.

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

  • 在第一遍中,搜索方法匹配而不允许装箱/拆箱(也不是变量arity方法).

    • 因为a null是可接受的值String而不是boolean,在此传递中Boolean.valueOf(null)匹配Boolean.valueOf(String);
    • Boolean对于任何一个Boolean.valueOf(String)或者是不可接受的Boolean.valueOf(boolean),因此在这个传递中没有匹配的方法Boolean.valueOf(modifiedItems.get("item1")).
  • 在第二遍中,搜索方法匹配,允许装箱/拆箱(但仍然不是可变的arity方法).

    • A Boolean可以取消装箱boolean,因此在此通道中Boolean.valueOf(boolean)匹配Boolean.valueOf(modifiedItems.get("item1")); 但是编译器必须插入一个取消装箱的转换才能调用它:Boolean.valueOf(modifiedItems.get("item1").booleanValue())
  • (第三次传递允许使用变量arity方法,但这里没有相关性,因为前两次传递匹配这些情况)

  • 如果我们在源代码中使用`Boolean.valueOf(modifiedItems.get("item1").booleanValue())`而不是`Boolean.valueOf(modifiedItems.get("item1"))`,代码可以更清楚吗? (3认同)

Mur*_*nik 13

由于modifiedItems.get返回一个Boolean(这是可浇注到一个String),将用于是签名Boolean.valueOf(boolean),其中,所述Boolean被地outboxed为原始boolean.一旦null返回那里,发件箱就失败了NullPointerException.


Al-*_*-un 11

方法签名

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

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

你的modifiedItems价值是Boolean.你不能投Boolean,String所以第一个签名将被选中

布尔取消装箱

在你的陈述中

Boolean.valueOf(modifiedItems.get("item1"))
Run Code Online (Sandbox Code Playgroud)

可以读作

Boolean.valueOf(modifiedItems.get("item1").booleanValue())   
Run Code Online (Sandbox Code Playgroud)

但是,modifiedItems.get("item1")返回null所以你基本上都有

null.booleanValue()
Run Code Online (Sandbox Code Playgroud)

这明显导致了一个 NullPointerException

  • 不要在我的帐户上删除它.请记住,这不是一个零和游戏:人们可以(并且做)提出多个答案. (4认同)