问题
我有这个代码:
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
}
}
我的问题是,我不明白为什么测试3件好(它打印false
并且不生产NullPointerException
)同时测试第4行aNullPointerException
。正如你在tests1and2,null
和modifiedItems.get("item1")
中看到的那样等于和null
。
Java 7和8中的行为是相同的。
#1 热门回答(167 赞)
你必须仔细查看正在调用的重载:
- Boolean.valueOf(null)正在调用Boolean.valueOf(String)。即使提供了null参数,也不会抛出NPE。
- Boolean.valueOf(modifiedItems.get("item1"))正在调用Boolean.valueOf(boolean),因为modifiedItems的值是Boolean类型,需要进行拆箱转换。由于modifiedItems.get("item1")为null,因此它是该值的拆箱 - 而不是Boolean.valueOf(...) - 它会抛出NPE。
确定调用哪个重载的规则是pretty hairy,但它们大致如下:
- 在第一遍中,搜索方法匹配而不允许装箱/拆箱(也不是变量arity方法)。因为null是String的可接受值而不是boolean,所以Boolean.valueOf(null)在此传递中与Boolean.valueOf(String)匹配;布尔值对于Boolean.valueOf(String)或Boolean.valueOf(boolean)是不可接受的,因此对于Boolean.valueOf(modifiedItems.get("item1")),此传递中没有匹配任何方法。
- 在第二遍中,搜索方法匹配,允许装箱/拆箱(但仍然不是可变的arity方法)。布尔值可以取消装箱为布尔值,因此在此过程中布尔值(布尔值)布尔值与布尔值相同(modifiedItems.get("item1"));但是编译器必须插入一个取消装箱转换才能调用它:Boolean.valueOf(modifiedItems.get("item1")。booleanValue())
- (第三次传递允许变量arity方法,但这里没有相关性,因为前两次传递匹配这些情况)
#2 热门回答(13 赞)
由于modifiedItems.get
返回aBoolean
(即而不是castable至aString
),将使用的签名是Boolean.valueOf(boolean)
,其中Boolean
的外包为原始boolean
。 Oncenull
返回那里,发件箱失败,aNullPointerException
。
#3 热门回答(11 赞)
##方法签名
方法Boolean.valueOf(...)
有两个签名:
- public static Boolean valueOf(boolean b)
- public static Boolean valueOf(String s)
YourmodifiedItems
value是Boolean
。你不能投射Boolean
到String
,因此将选择第一个签名
Boolean取消装箱
在你的陈述中
Boolean.valueOf(modifiedItems.get("item1"))
可以读作
Boolean.valueOf(modifiedItems.get("item1").booleanValue())
但是,modifiedItems.get("item1")
returnsnull
你基本上都有
null.booleanValue()
这显然导致aNullPointerException