Odd Java ternary behavior when assigning value. What is Java doing behind the scenes for this to happen?

Tim Z. :

A few days ago, I ran into a fascinating scenario that I couldn't find any documentation on how or why Java lets the following happen. (This snippet is just a simplified form of the bug.)

    @Test
    public void test() {
      boolean bool = false;
      Integer intVal = Integer.valueOf(5);
      Long longVal = null;
      Long result = bool ? intVal : longVal;

      System.out.println(" > " + result);
   }

in the snippet above:

if the bool = true, then you get the value '5';

but if bool = false, then you get a null pointer exception when trying to evaluate the ternary operation. NOT the print statement.


To fix this I just change 'result' to

Long result = bool ? Long.valueOf(intVal) : longVal;

Doing this, will give the expected behavior I needed:

if the bool = true, then you get the value '5';

but if bool = false, then you get 'null'


now the fun part is that if you split this into a normal if/else statement, then java does NOT let you compile

longVal = intVal; 

but it doesnt catch that via the ternary operator. So what's Java doing to make it null point in the original snippet?

(java 11)

Diego Magdaleno :

When you do this:

Long result = bool ? intVal : longVal

This expression is returning a long and, when bool is false it tries to unboxe null to a Long value to fit the result variable and throws a NPE.

When you do this:

Long result = bool ? Long.valueOf(intVal) : longVal

This expression is already returning Long then there is no need for unboxing and the null value is successfully assigned to the result variable.

Reference:

As discussed in the comments section, to better understand why does this happen, check the following sections of the JLS:

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=4257&siteId=1