问题描述
当我写这样的java代码时:
When I write my java code like this:
Map<String, Long> map = new HashMap<>()
Long number =null;
if(map == null)
number = (long) 0;
else
number = map.get("non-existent key");
该应用程序按预期运行但当我这样做时:
the app runs as expected but when I do this:
Map<String, Long> map = new HashMap<>();
Long number= (map == null) ? (long)0 : map.get("non-existent key");
我在第二行得到NullPointerException。调试指针从第二行跳转到java.lang.Thread类中的此方法:
I get a NullPointerException on the second line. The debug pointer jumps from the second line to this method in the java.lang.Thread class:
/**
* Dispatch an uncaught exception to the handler. This method is
* intended to be called only by the JVM.
*/
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
这里发生了什么?这两个代码路径都是完全等价的不是吗?
What is happening here? Both these code paths are exactly equivalent isn't it?
编辑
我使用的是Java 1.7 U25
I am using Java 1.7 U25
推荐答案
它们不等同。
此表达式的类型
(map == null) ? (long)0 : map.get("non-existent key");
是 long
因为真实结果有类型 long
。
is long
because the true result has type long
.
此表达式的类型为 long
来自JLS的部分:
The reason this expression is of type long
is from section §15.25 of the JLS:
当您查找不存在的密钥时,地图
返回 null
。因此,Java正试图将其拆分为 long
。但它是 null
。所以它不能,你得到一个 NullPointerException
。您可以通过以下方式解决此问题:
When you lookup a non-existant key the map
returns null
. So, Java is attempting to unbox it to a long
. But it's null
. So it can't and you get a NullPointerException
. You can fix this by saying:
Long number = (map == null) ? (Long)0L : map.get("non-existent key");
然后你就没事了。
但是,这里,
if(map == null)
number = (long) 0;
else
number = map.get("non-existent key");
因为数字
被声明为长
,取消装箱到长
永远不会发生。
since number
is declared as Long
, that unboxing to a long
never occurs.
这篇关于使用Java三元运算符时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!