I am trying to understand the following code. Line number 2 outputs null while line 3 throws NullPointerException. What am I missing ? Theoretically it should work.
public static void main(String []args){
1 Object[] obj = {null};
2 System.out.println((Integer)obj[0]); //Output null
3 Integer n = obj[0] == null ? (Integer)obj[0] : 1; //NullPointerException
4 System.out.println(n);
}
Based on the rules defined in the JLS, the type of the ternary conditional operator
null ? (Integer)obj[0] : 1;
is int
, not Integer
.
Hence, when the result of this expression is (Integer)obj[0]
, the Integer
is unboxed to int
, and you get NullPointerException
.
See JLS 15.25. Conditional Operator ? :, Table 15.25-A. :
Since your second operand is Integer
and your third operand is int
, the conditional expression type is int
.
The key concept here is binary numeric promotion.
When you supply an operator with operands of different types, the operands have to be are converted to be compatible with one another. The conditional operator's rules for this conversion are reasonably complicated; but when the operands are of differing types, and are convertible to numbers, binary numeric promotion is applied.
In the case of supplying one boxed and one primitive operand, the effect of binary numeric promotion is to attempt to unbox the boxed operand, not to box the primitive operand.
You get can observe binary numeric promotion with other multi-operand operators, for example +
:
System.out.println(1 + (Integer) null); // NullPointerException!
With the conditional operator, you would not get a NPE if you explicitly box the 1, because the operands are then not of differing types:
Integer n = obj[0] == null ? (Integer)obj[0] : Integer.valueOf(1);
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