3

I need to be able to compare two variables, which might at some times be null. If they're both null, I still want it to be considered equal. Is there any appropriate way to do this?

I was testing it out in NetBeans, and looking at the documentation for .equals(), and saw that null references behave weirdly.

These are my examples and results:

Object a = null, b = null;
System.out.println(a == b);

returns true.

OR:

System.out.println(a.equals(b));

throws NullPointerException.

Does == work how I want it to in this case, or am I just 'getting lucky' here and it came to the conclusion 'true' for some other reason?

The NullPointerException is also confusing me, as I always understood Object's equals method to be a reference equality. The documentation repeatedly states 'non-null' Objects, but why would that matter for a reference comparison? Any clarification would be greatly appreciated.

5
  • 8
    Objects.equals(a,b); Commented Jun 16, 2015 at 19:06
  • 3
    Objects aren't null. You need to start differentiating between variables, references, and objects. Commented Jun 16, 2015 at 19:08
  • 1
    @OP: The answers you've received will help you understand what went wrong. But after you understand all that, you'll want to pay attention to what Hubert suggested, which is exactly what you are after.
    – sstan
    Commented Jun 16, 2015 at 19:09
  • 2
    null is not an object, or an instance. it does not have a class, you can't call methods on it, or use it for anything (except things that actually handle null). null is always equal to null, in the sense of ==. equals on null does not make sense, because it means these 2 instances are the same in a functional sense
    – njzk2
    Commented Jun 16, 2015 at 19:09
  • 1
    @njzk2 this reminds me a passage about love from the bible. :) Commented Jun 16, 2015 at 20:49

3 Answers 3

10

The == operator tests whether two variables have identical value. For object references, this means that the variables must refer to the same object (or both variables must be null). The equals() method, of course, requires that the variable on which it is invoked not be null. It's behavior depends on the type of object being referenced (on the actual object, not on the declared type). The default behavior (defined by Object) is to simply use ==.

To get the behavior you want, you can do:

System.out.println(a == null ? b == null : a.equals(b));

NOTE: as of Java 7, you can use:

System.out.println(java.util.Objects.equals(a, b));

which does the same thing internally.

1

a.equals(b) returns a NullPointerException because it's literally

null.equals(...)

and null doesn't have a .equals (or any other method).

same thing with b.equals(a)

a == b returns true because it's null == null (obviously true). So to compare you have to check a and b for null or something like...

if (a != null) 
   return a.equals(b);  // This works because a is not null.  `a.equals(null)` is valid.  
else if (b != null) 
   return b.equals(a);  // a is null, but b is not
else 
   return a == b;

the ?: operator is a bit more concise for this

2
  • I don't think you need to test for b != null. All you need at that point is to return true if b == null. No sane implementation of equals() will return true if the argument is null (and a must be null in that branch). If it does, then it would have to return true for all arguments, since the contract for Object#equals is that it must implement an equivalence relation.
    – Ted Hopp
    Commented Jun 16, 2015 at 19:21
  • Yeah, agreed. I wrote the extra if statement for completeness in my example... even if it's extraneous
    – Shaun
    Commented Jun 16, 2015 at 19:22
1

You cannot invoke a method like equals on null value. If you want use a method saftly you must check null value like

if(a!=null)
    System.out.println(a.equals(b));
else
    System.out.println(a==b));

Not the answer you're looking for? Browse other questions tagged or ask your own question.