[英]Weird behaviour when using Java ternary operator
当我写这样的java代码时:
Map<String, Long> map = new HashMap<>()
Long number =null;
if(map == null)
number = (long) 0;
else
number = map.get("non-existent key");
应用程序按预期运行但是当我这样做时:
Map<String, Long> map = new HashMap<>();
Long number= (map == null) ? (long)0 : map.get("non-existent key");
我在第二行得到一个NullPointerException。 调试指针从第二行跳转到java.lang.Thread类中的this方法:
/**
* 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);
}
这里发生了什么? 这两个代码路径都完全等价不是吗?
编辑
我使用的是Java 1.7 U25
他们并不等同。
这个表达式的类型
(map == null) ? (long)0 : map.get("non-existent key");
很long
因为真正的结果类型long
。
如果第二和第三个操作数中的一个是原始类型的
T
,其它的类型是施加装箱转换(§5.1.7)到的结果T
,那么条件表达式的类型是T
。
查找不存在的键时, map
返回null
。 因此,Java试图将其拆箱很long
。 但它是null
。 所以它不能,你得到一个NullPointerException
。 您可以通过说:
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
永远不会发生。
我在上面评论过,他建议他确保map
永远不会为null
,但这对三元问题没有帮助。 实际上,让系统为您完成工作更容易。 他可以使用Apache Commons Collections 4及其DefaultedMap类。
import static org.apache.commons.collections4.map.DefaultedMap.defaultedMap;
Map<String, Long> map = ...; // Ensure not null.
Map<String, Long> dMap = defaultedMap(map, 0L);
谷歌番石榴没有那么简单,但可以使用Maps.transformValues()
方法包装map
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.