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
。 正如您在testing1和2中看到的那样, null
和modifiedItems.get("item1")
是equals和null
。
Java 7和8中的行为是相同的。
你必须仔细看看哪个过载被调用:
-
Boolean.valueOf(null)
调用Boolean.valueOf(String)
。 即使提供了null参数,这也不会引发NPE
。 -
Boolean.valueOf(modifiedItems.get("item1"))
正在调用Boolean.valueOf(boolean)
,因为modifiedItems
的值是Boolean
types的,需要进行拆箱转换。 由于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
,所以在这个boolean
,Boolean.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(...)
有两个签名:
-
public static Boolean valueOf(boolean b)
-
public static Boolean valueOf(String s)
您的modifiedItems
值是Boolean
。 您不能将Boolean
为String
,因此将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,也可能产生NullPointerException
exception。
- 字节 – 字节
- 字符 – 字符
- 浮动 – 浮动
- int – 整数
- 长隆
- 短 – 短
- 双 – 双
这里是代码:
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