为什么我在这里收到一个NullPointerException异常?

4
Long n = null;
for (Long price : new Long[]{null, 2L, 10L}) {          
n = (n != null) ? 0L : price;   
}

我被难住了,为什么执行这段代码时会出现NPE? 似乎只是将n赋值为null的price,很简单的操作。 不用担心它的意义,它毫无意义。


3
这段代码完全没有意义。 - Thomas Jungblut
NPE被抛出的是哪一行? - skaffman
这行代码,n = (n != null) ? 0L : price; - bouncyrabbit
1
可能应该是:n = (price == null) ? 0L : price; - jontro
你的意图是要检查 price 是否为 null 吗? - J Lundberg
好的,无论如何,n =(n == null)?0L:price; 这也会抛出NPE。 - bouncyrabbit
6个回答

10
在这条代码中 n = (n != null) ? 0L : price;,你的?:语句的替代方案有一个long和一个Long。Java将其解释为long类型,并尝试取消装箱Long,而不是装箱long。 当price为null时,正如在第一次迭代中一样,这会生成NPE异常。

3
这是因为价格被展开以匹配三元运算符中的0L返回可能性。请尝试以下方法:
Long n = null;
for (Long price : new Long[]{null, 2L, 10L}) {          
    n = (n != null) ? new Long(0L) : price;   
}

一切都会顺利进行。


2

这条线

n = (n != null) ? 0L : price;   

编译成

n = Long.valueOf(n == null ? price.longValue() : 0L);

pricenull时,语句price.longValue()会抛出NullPointerException异常。尝试用new Long[] {1L, 2L, 3L}替换数组并查看其效果。


2

如果你查看字节码,就会发生这种情况。

 49:    invokevirtual   #26; //Method java/lang/Long.longValue:()J
 52:    invokestatic    #20; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long;

在进行比较时,对该数组中的每个项执行Long.longValue,导致您的NullPointerException。问题是三元表达式与自动装箱相结合,使得实际发生的事情变得模糊。


1

尝试

 n = (price != null) ? price : 0L;

你改变了逻辑 -- 你正在测试 price 而不是 n。尽管如此,这可能是 OP 真正想要的,但它并没有回答为什么会抛出 NPE 的问题。 - Dave Costa

0

它试图将price强制转换为原始类型long,以匹配0L的类型。如果pricenull,则会生成NPE。

此表达式有效,因为它避免了隐式类型转换:

n = (n != null) ? new Long( 0L ) : price ;

但正如其他评论中所说的那样,你在这里做的事情似乎也没有太多意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接