Java的简写forms如果返回的对象之一为null,则返回NullPointerException
为什么此代码返回错误:java.lang.NullPointerException
Object obj = null; Long lNull = null; Long res = obj == null ? lNull : 10L;
但是以下方式可以正常运行:
Object obj = null; Long res = obj == null ? null : 10L;
在第二种情况下,编译器可以推断出null
必须是Long
类型。 在第一种情况下,它没有 – 并假设表达式返回long
。 你可以看到这种情况(即修复它),如,
Long res = obj == null ? lNull : (Long) 10L;
它不会产生NullPointerException。
发生错误是因为在您的情况下,标准要求取消装箱的类型值 :
如果第二个和第三个操作数之一是原始类型
T
,而另一个操作数的类型是对T
应用装箱转换(第5.1.7节)的结果,那么条件表达式的类型是T
在你的情况下, T
很long
,因为10L
很long
而lNull
是Long
, lNull
boxing转换应用于long
。
标准进一步说明了这一点
如有必要,将对结果执行取消装箱转换。
这是导致exception的原因。 请注意,如果反转条件,则不再抛出exception:
Long res = obj != null ? lNull : 10L;
您可以通过明确要求Long
而不是使用long
来解决问题,即
Long res = obj == null ? lNull : Long.valueOf(10L);
JLS,第15.25节讨论了第二和第三个操作数类型的各种组合的条件运算符表达式的类型。 有许多表将所有相关组合中的两种类型映射到结果类型。
3rd → long 2nd ↓ ... Long long ... null lub(null,Long)
你的第一个例子有一个Long
和一个long
,结果long
。 这需要将lNull
取消装箱,这解释了NullPointerException
。
你的第二个例子有一个null
文字 (不是null
变量)和一个long
文本 。 这导致“lub(null,Long)”或Long
,并且不执行拆箱,因此未观察到NPE。
您可以通过使用第一个示例或将10L
为Long
来避免NPE,因为null
和Long
产生Long
。
3rd → Long 2nd ↓ ... Long Long