簡體   English   中英

java:三元運算符(?:)中的NullPointerException很奇怪

[英]java: weird NullPointerException in ternary operator (? : )

請考慮以下代碼片段:

private static void doSomething(Double avg, Double min, Double sd) {
    final Double testMin;
    if (avg != null) {
        testMin = Math.max(min, avg - 3 * sd);
    } else {
        testMin = min;
    }
    System.out.println("testMin=" + testMin);

    final Double verwachtMin = avg != null ? Math.max(min, avg - 3 * sd) : min;
    System.out.println("verwachtMin=" + verwachtMin);
}

據我所知(以及我的IDE可以告訴我的),變量testMinverwachtMin應該等效。

如您所料,我寧願寫最后2行而不是前7行。但是,當我向該方法傳遞3個空值時,我在verwachtMin變量的計算中得到了NPE。

有人知道這怎么可能嗎? 即使條件不true ,三元運算符也會評估第二部分嗎?

(Java版本1.6.0_21)

嘗試:

final Double verwachtMin = avg != null ? new Double(Math.max(min, avg - 3 * sd)) : min;

要么

final Double verwachtMin = avg != null ? Double.valueOf(Math.max(min, avg - 3 * sd)) : min;

三元運算符的交替邊的類型是doubleDouble ,這意味着Double取消裝箱而成為double ,然后在賦值時,我們將裝箱從double改為Double 如果min值為null則取消裝箱NPE。

即使條件不成立,三元運算符也會評估第二部分

否-但是它會評估第3部分,在這種情況下,我認為它會嘗試自動取消裝箱min (導致NPE),因為Math.max()的返回類型是原始double並確定整個表達式的返回類型。

自動裝箱/拆箱很簡單。

問題是由自動裝箱 *引起的,而不是由三元運算符引起的。 您正在使用Double包裝器類型,而不是double基本類型。 因為Math.max()需要double參數,而不是Double s,所以在將值傳遞給Math.max()之前,對Double#doubleValue()進行了不可見的調用。 但是,您不能在null對象上調用方法-因此會導致NullPointerException

為什么首先使用Double而不是double 基本類型變量(例如double )根本不能為null


*在這種情況下,自動拆箱

自動拆箱會導致此問題。 之前曾問過類似的問題。.您可以使用double而不是Double來解決您的問題。

Math.max(min, avg - 3 * sd)在此處minavgsd從Double自動展開為double裝箱,如果其中之一為null會導致NPE。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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