开发者

java: weird NullPointerException in ternary operator (? : )

Please consider this code snippet:

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);
}

As far as I know (and for what my IDE can tell me), the variables testMin and verwachtMin should be equivalent.

As you might expect, I'd rather write the last 2 lines than the first 7. However, when I pass 3 null values to this method, I get an NPE on the calculation of the verwachtMin variable.

Does anyone know how this can happen? Does the ternary operator evaluate the 2nd part, even when the condition is not true?

(Java version 1.6.0_21)


Try:

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

or

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

The types of the alternate sides of the ternary operator were double and Double, which means that the Double gets unboxed to double, and then on assignment we have a boxing from double to Double. If the value of min is null then the unboxing NPEs.


Does the ternary operator evaluate the 2nd part, even when the condition is not true

No - but it evaluates the 3rd part and I think in this case it tries to autounbox min (leading to the NPE) because the return type of Math.max() is primitive double and determines the return type of the entire expression.

Autoboxing/-unboxing is of the devil.


The problem is caused by autoboxing*, not by the ternary operator. You are using the Double wrapper type rather than the double primitive type. Because Math.max() expects double parameters, not Doubles, there is an invisible call to Double#doubleValue() before the values are passed to Math.max(). However, you can't call a method on a null object - hence the NullPointerException.

Why are you using Double instead of double in the first place? A primitive-type variable (such as a double) simply cannot be null.


*Well, autounboxing, in this case


Auto-unboxing causes the problem. Similar question has been asked before .. You sould use double instead of Double to solve your problem..


Math.max(min, avg - 3 * sd) here min, avg and sd are autounboxed from Double to double which when one of them is null causes an NPE.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜