We've run into following java function that models some variation of NULL arithmetic:
public static Long add(Long value1, Long value2) { return value1 == null ? value2 : value2 == null ? value1 : value1 + value2; }
When this function runs the outcome is different from what we have expected.
Here is a quiz:
What is outcome of add(1, 2):
add(1, 2)
3
null
What is outcome of add(3, null):
add(3, null)
What is outcome of add(null, 4):
add(null, 4)
4
What is outcome of add(null, null):
add(null, null)
0
Our assumptions were:
add(1, 2) == 3
add(3, null) == 3
add(null, 4) == 4
add(null, null) == null
Java works differently:
add(3, null) throws NullPointerException
add(null, 4) throws NullPointerException
add(null, null) throws NullPointerException
The problem is with compile time type of ternary ?: operator. Compiler decides it's long, while we intuitively expected Long. Java casts null to long (which results into NPE), and then to Long.
?:
long
Long
NPE
Correct code would be:
public static Long add(Long value1, Long value2) { if (value1 == null) { return value2; } else if (value2 == null) { return value; } else { return value1 + value2; } }
This version does not cast anything to long, and works as we originally expected.
Honestly, we're a bit anexious about this subtle difference of if-then-else and ?: operator.
if-then-else