[英]Why is Java evaluating the wrong side of ternary operation?
我可能會錯過一些簡單的解釋,但以下行拋出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())
返回空值。 fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())
的返回類型為 Long。
fiscalDocument.getReceipt().getAmount()
的返回類型是Integer
。
如果我發出顯式(長)轉換,則行為是相同的。
編輯 2
一個最小的可重復示例: Long val =true ? (Long) null: Integer.valueOf(1);
Long val =true ? (Long) null: Integer.valueOf(1);
. 這部分是由 MC Emperor 的回答所建議的,部分是由評論所建議的。 當然,這個例子已經在某種程度上回答了這個問題,因為事實證明,第二個表達式不需要拋出異常。
如果foo
類型為Long
並且bar
類型為long
,那么為true ? foo : bar
true ? foo : bar
類型為long
,等價於true ? foo.longValue() : bar
true ? foo.longValue() : bar
。 正如Java 語言規范所說:
如果第二個和第三個操作數之一是原始類型 T,另一個的類型是對 T 應用裝箱轉換(第 5.1.7 節)的結果,則條件表達式的類型為 T。
(在您的情況下, T
是long
,並且“將裝箱轉換(第 5.1.7 節)應用於 T 的結果”是Long
。)
您嘗試將結果放入Long
變量這一事實不會改變這一事實; 它只是給你相當於Long.valueOf(true ? foo.longValue() : bar)
,先拆箱再裝箱。
在您的情況下, foo == null
,因此取消裝箱會引發 NullPointerException,因此裝箱永遠不會發生。
好吧,Java 只計算左表達式,因為條件為true
。
你說fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())
本身不會拋出NullPointerException。
我能想到的唯一一件事是fiscalDocumentUtil.getFullValue(fiscalDocument.getInvoice())
返回null
。 可重現:
Long sum = true ? null : (long) 23L;
因為其中一個操作數是一個原語,另一個需要進行裝箱轉換,在這種情況下,取消裝箱為long
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.