使用 Java 三元运算符时的奇怪行为 [英] Weird behaviour when using Java ternary operator
问题描述
当我像这样编写 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 第 15.25 节:
The reason this expression is of type long
is from section §15.25 of the JLS:
如果第二个和第三个操作数之一是原始类型T
,而另一个的类型是对T
应用装箱转换(第5.1.7节)的结果code>,则条件表达式的类型为T
.
If one of the second and third operands is of primitive type
T
, and the type of the other is the result of applying boxing conversion (§5.1.7) toT
, then the type of the conditional expression isT
.
当您查找不存在的键时,map
返回 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");
因为 number
被声明为 Long
,所以永远不会发生对 long
的拆箱.
since number
is declared as Long
, that unboxing to a long
never occurs.
这篇关于使用 Java 三元运算符时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!