Java if
-statements use something called short-circuit evaluation, where if there is an &&
where the first condition is false
, or an ||
where the first condition is true
, then it will not evaluate the rest of the condition, because it already knows what the result will be. If there is an &&
and the first statement is false
, then it doesn't matter what the rest of the statements evaluate to, since the whole thing is false, and vice-versa if there is an ||
and the first statement is true.
A second issue is that if an object is null
, then calling any method or accessing any property of the function will throw a NullPointerException. This can be avoided by checking if an object is null
before using it in cases where you know it might be null
. In your linked list, evidently you are concerned that a node might be null
, so you check before accessing its next
.
These two combine together in your example. If you do
if (item != null && item.property != null) {}
and item
is actually null, then because of short-circuit evaluation, Java will never actually check item.property
to see if it's null
as well, because it already knows the combined statement will be false.
Conversely, if you do
if (item.property != null && item != null) {}
then Java will try to access item.property
, which will throw a NullPointerException
if item
is null
.
In your case, evidently many of your test cases had situations where fast
was null at some point. The example where they passed would have avoided calling fast.next
when fast
is null because of short-circuit evaluation, whereas the second example never avoids the NullPointerException
s at all.