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 Double
s, 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.
精彩评论