I tripped across a really strange NullPointerException
the other day caused by an unexpected type-cast in the ternary operator. Given this (useless exemplary) function:
Integer getNumber() {
return null;
}
I was expecting the following two code segments to be exactly identical after compilation:
Integer number;
if (condition) {
number = getNumber();
} else {
number = 0;
}
vs.
Integer number = (condition) ? getNumber() : 0;
.
Turns out, if condition
is true
, the if
-statement works fine, while the ternary opration in the second code segment throws a NullPointerException
. It seems as though the ternary operation has decided to type-cast both choices to int
before auto-boxing the result back into an Integer
!?! In fact, if I explicitly cast the 0
to Integer
, the exception goes away. In other words:
Integer number = (condition) ? getNumber() : 0;
is not the same as:
Integer number = (condition) ? getNumber() : (Integer) 0;
.
So, it seems that there is a byte-code difference between the ternary operator and an equivalent if-else
-statement (something I didn't expect). Which raises three questions: Why is there a difference? Is this a bug in the ternary implementation or is there a reason for the type cast? Given there is a difference, is the ternary operation more or less performant than an equivalent if
-statement (I know, the difference can't be huge, but still)?