java: weird NullPointerException in ternary operator (? : )

天大地大妈咪最大 提交于 2019-11-29 13:38:32

问题


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)


回答1:


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.




回答2:


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.




回答3:


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




回答4:


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




回答5:


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.



来源:https://stackoverflow.com/questions/5246776/java-weird-nullpointerexception-in-ternary-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!