Phoenix
Phoenix

Reputation: 8923

Equals and NullPointerException

@Test
public void testDoc()
{

   String a1 = "123"
   String b1 = null;

   String a2 = null
   String b2 = "456";

   boolean westId1 =
   (a1 == b1) || ((a1 != null)&& b1.equals(a1));
   println westId1

   boolean westId2 =
   (a2 == b2) || ((a2 != null)&& b2.equals(a2));
   println westId2


}

Why don't I get a NPE on b1.equals(a1) ? when b1 is null ?

Upvotes: 0

Views: 324

Answers (2)

tim_yates
tim_yates

Reputation: 171114

This is groovy, so you're into the wonderful world of NullObject

If you do this:

b = null
println b.getClass().name

It will print:

'org.codehaus.groovy.runtime.NullObject'

So b is an instance of NullObject. And NullObject has an equals method defined as:

public boolean equals(Object to) {
    return to == null;
}

So this is why you don't get the NPE. Short circuiting rules do apply to logical statements such as this, but the statements in the question do not get short circuited, the equals just gets handled by Groovy.

Try it out:

println null.equals( 4 ) // prints 'false'

Upvotes: 3

Rahul
Rahul

Reputation: 45070

You do get a NPE at b1.equals(a1), because your b1 is null & null.anyMethod() would throw that exception.

Had your a1 been null too, then you wouldn't have got the NPE, because of the && operator, which wouldn't evaluate the rest of the condition, once it has encountered a false.

The || needs a true and the && needs a false to short-circuit!

See this to learn more about this concept called, Short-Circuit Evaluation.

Update:- For your case, it going to be like this:-

boolean westId1 = (a1==null && b1==null) || (a1!=null && b1!=null && a1.equals(b1));

You can always simplify it, but I gave the condition based on your requirement, so that it would help you understand better!

Upvotes: 1

Related Questions