public class Npe {
static class Thing {
long value;
}
public static Map<Thing, Long> map;
public static void main(String[] args) {
Thing thing = new Thing();
method(null); // returns -1
method(thing); // returns 0
map = new HashMap<Thing, Long>();
method(null); // returns -1
method(thing); // NullPointerException thrown inside this method call
}
public static long method(Thing thing) {
if (thing == null) {
return -1;
}
Long v = (map == null) ? thing.value : map.get(thing); // NPE here
if (v == null) {
v = thing.value;
}
return v;
}
}
On the 4th call to method()
I get a NullPointerException
thrown on the indicated line inside method()
. If I refactor that line from
Long v = (map == null) ? thing.value : map.get(thing);
to
Long v;
if (map == null) {
v = thing.value;
} else {
v = map.get(thing);
}
I get no NullPointerException
and the method behaves as it should. The question is: WHY??
It looks to me like the compiler expects the result of the ?
operator to be long
so that it is automatically unboxing (demoting from Long
to long
) the result of the call to map.get(thing)
(which may return null
and therefore throw a NullPointerException
). IMHO it should be expecting the result of the ?
operator to be Long
and autoboxing (promoting long
to Long
) thing.value
instead.
Even better, if I refactor this statement:
Long v = (map == null) ? thing.value : map.get(thing);
to this (casting long
to Long
explicitly):
Long v = (map == null) ? (Long)thing.value : map.get(thing);
my IDE (IntelliJ) says that the cast is redundant, but the compiled code works as expected and does not throw a NullPointerException
! :-D