[英]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可以告訴我的),變量testMin
和verwachtMin
應該等效。
如您所料,我寧願寫最后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;
三元運算符的交替邊的類型是double
和Double
,這意味着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)
在此處min
, avg
和sd
從Double自動展開為double裝箱,如果其中之一為null會導致NPE。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.