1

我可能会错过一些简单的解释,但下面一行会抛出一个NullPointerException

Long sum = true 
           ? 
           fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) 
           :
           (long) fiscalDocument.getReceipt().getAmount();

尽管

Long sum = true 
           ? 
           fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) 
           :
           null

才不是。我还想提一下

fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())

不会自行抛出异常,而

(long) fiscalDocument.getReceipt().getAmount()

做。

是否对第二方进行评估?还是我在屠杀什么?

编辑

评论中询问的一些附加信息: fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())返回 null。的返回类型fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())是 Long。

的返回类型fiscalDocument.getReceipt().getAmount()Integer

如果我发出显式(长)转换,则行为是相同的。

编辑 2

一个最小的可重现示例:Long val =true ? (Long) null: Integer.valueOf(1);. MC Emperor 的回答部分暗示了这一点,评论部分暗示了这一点。当然,这个例子已经在一定程度上回答了这个问题,因为事实证明,第二个表达式不需要抛出异常。

4

2 回答 2

4

如果foo有类型Long并且bar有类型long,那么true ? foo : bar有类型long,并且等价于true ? foo.longValue() : bar。正如Java 语言规范 所说

如果第二个和第三个操作数之一是原始类型 T,而另一个的类型是对 T 应用装箱转换(第 5.1.7 节)的结果,则条件表达式的类型是 T。

(在您的情况下,Tlong,并且“将装箱转换(第 5.1.7 节)应用于 T 的结果”是Long。)

您尝试将结果放入Long变量中的事实并没有改变这一事实。它只是给你相当于Long.valueOf(true ? foo.longValue() : bar), 拆箱后装箱。

在您的情况下foo == null,因此拆箱会引发 NullPointerException,因此装箱永远不会发生。

于 2021-11-10T08:23:25.170 回答
1

好吧,Java 只计算左表达式,因为条件是true.

你说它fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())本身不会抛出 NullPointerException。

我唯一能想到的就是fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice()) 返回 null。可重现:

Long sum = true ? null : (long) 23L;

因为其中一个操作数是原语,所以另一个要进行装箱转换,在这种情况下,取消装箱到long

于 2021-11-10T08:40:20.243 回答