簡體   English   中英

為什么 Java 評估三元運算的錯誤方面?

[英]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。

(在您的情況下, Tlong ,並且“將裝箱轉換(第 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM