Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting Null Object into Integer [duplicate]

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);
 }
like image 347
Adeel Avatar asked Dec 18 '22 15:12

Adeel


2 Answers

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.

like image 52
Eran Avatar answered Jan 13 '23 11:01

Eran


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);
like image 26
Andy Turner Avatar answered Jan 13 '23 12:01

Andy Turner