Boolean.valueOf() 有时会产生 NullPointerException [英] Boolean.valueOf() produces NullPointerException sometimes

查看:24
本文介绍了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
    }
}

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

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.

Java 7 和 8 中的行为相同.

The behavior is the same in Java 7 and 8.

推荐答案

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

You've got to look carefully at which overload is being invoked:

  • Boolean.valueOf(null) 正在调用 Boolean.valueOf(String).即使提供了空参数,这也不会抛出 NPE.
  • Boolean.valueOf(modifiedItems.get("item1")) 正在调用 Boolean.valueOf(boolean),因为modifiedItems的值是类型Boolean,需要进行拆箱转换.由于 modifiedItems.get("item1")null,它是该值的拆箱 - 而不是 Boolean.valueOf(...) - 抛出 NPE.
  • 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:

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

  • In a first pass, a method match is searched for without allowing boxing/unboxing (nor variable arity methods).

  • 因为 nullString 但不是 boolean 的可接受值,所以 Boolean.valueOf(null)在这个pass中匹配到Boolean.valueOf(String)
  • BooleanBoolean.valueOf(String)Boolean.valueOf(boolean) 都是不可接受的,所以没有方法是在此传递中匹配 Boolean.valueOf(modifiedItems.get("item1")).
  • 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).

  • Boolean 可以拆箱为 boolean,所以 Boolean.valueOf(boolean)Boolean.valueOf(modifiedItems.get("item1")) 在这个pass中;但是编译器必须插入一个拆箱转换来调用它:Boolean.valueOf(modifiedItems.get("item1").booleanValue())
  • 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)

这篇关于Boolean.valueOf() 有时会产生 NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆