Why is this fine with x being set to null:
boolean condition1 = false;
Integer x = condition1 ? 1 : null;
And this fine with x being set to 2:
boolean condition1 = false, condition2 = true;
Integer x = condition1 ? 1 : condition2? 2 : null;
But this, where x should be set to null causes a java.lang.NullPointerException
boolean condition1 = false, condition2 = false;
Integer x = condition1 ? 1 : condition2 ? 2 : null;
A solution is to use:
Integer x = condition1 ? (Integer)1 : condition2 ? 2 : null;
But I'm not very clear on why a single ternary operator works fine, but not a double.
(I still think this is a duplicate after you've done a bit of unpacking, but hey...)
Expand the one statement into two:
// Not exactly the same, but close...
Integer tmp = condition2 ? 2 : null;
Integer x = condition1 ? 1 : (int) tmp;
That's not exactly the same because it evaluates condition2 ? 2 : null
even when condition1
is false - you could model it with a method call instead, but in the case you're worrying about, both condition1
and condition2
are false.
Now, you may ask why we've got the cast to int
here. That's because of JLS 15.25.2:
The type of a numeric conditional expression is determined as follows:
- ...
- If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.
- ...
We have int
and Integer
, so this matches for T = int
... and the result of the "inner" conditional expression is unboxed if necessary... and that's what's causing a problem.
Casting the 1
to Integer
changes this so that the type of the outer expression is Integer
too (because both the second and third operands then have type Integer
) so there's no unboxing.
Note that in our expansion, tmp
is an Integer
, and that really is the type of the "inner" conditional expression, because the type of the third operand is the null type, not Integer
. You can make it fail with just the one conditional too:
Integer bang = false ? 2 : (Integer) null;
Basically, a conditional operator with second and third operands of type int
and Integer
respectively will perform unboxing of the third operand (and the result is type int
), but a conditional operator with second and third operands of type int
and null
respectively will not unbox, and the result type is Integer
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With