45

Is there a method in the JDK that compares two objects for equality, accounting for nulls? Something like this:

public static boolean equals(Object o1, Object o2)
{
    if (o1 == null)
    {
        return o2 == null; // Two nulls are considered equal
    }
    else if (o2 == null)
    {
        return false;
    }

    return o1.equals(o2);
}

It seems silly to write this method myself since I would think that it has to exist already somewhere.

0

7 Answers 7

76

Java 7.0 added a new handy class: Objects.

It has a method exactly for this: Objects.equals(Object a, Object b)

4
  • Well, bear in mind that Java 7 is not yet universally available. I generally try not to use an API until its deployment has reached at least 95% Commented Jul 11, 2015 at 20:26
  • 6
    @EdwardFalk Yes, and also bear in mind that Java 7 (or any other version) will never reach 100% availability ever. Today it's July 12, 2015, Java 7 is exactly 4 years old, Java 6 is 9 years old. Even Java 7 reached end of life which means there will be no more public updates even for Java 7. Why would you encourage using only Java 6.0 API? Yes, there are computers which only have Java 6.0, but personally I don't want to develop software for systems being a decade old, at the expense of giving up the features added in Java 7 and 8.
    – icza
    Commented Jul 12, 2015 at 7:37
  • Yes, that's my working style. I only started using Java 6 features in the last few years, and do not yet use Java 7 or 8 features. I've been that way all my life; I didn't start using Ansi C until K&R C was no longer available anywhere. I'll use new features when I need them, but whenever possible, I prefer that my code compile and run everywhere. Commented Jul 12, 2015 at 18:07
  • It fails for complex objects and hence not very useful.
    – saran3h
    Commented May 5, 2021 at 9:14
17

Apache Commons Lang has such a method: ObjectUtils.equals(object1, object2). You don't want generics on such a method, it will lead to bogus compilation errors, at least in general use. Equals knows very well (or should - it is part of the contract) to check the class of the object and return false, so it doesn't need any additional type safety.

4
  • Yes, I suppose that generics really don't buy you anything in this case. You could still pass in completely different types and the type inference will just select Object as the type parameter. I'm not sure what the "bogus compilation errors" you are referring to are though.
    – dcstraw
    Commented Sep 9, 2009 at 21:17
  • I have definitely seen attempts to do generics like that have issues (with generic parameters, and the like). I couldn't quickly reproduce it in this scenario, so you may be right, but if so, then the generics are pointless, as they will accept anything, so why not just declare Object?
    – Yishai
    Commented Sep 9, 2009 at 21:24
  • 1
    Agreed. Using Object is better in this case.
    – dcstraw
    Commented Sep 9, 2009 at 21:36
  • Generics are useless in this case.
    – Steve Kuo
    Commented Sep 10, 2009 at 3:37
16

FWIW, this was my implementation:

private static boolean equals(Object a, Object b) {
    return a == b || (a != null && a.equals(b));
}

In my application, I know that a and b will always be the same type, but I suspect this works fine even if they aren't, provided that a.equals() is reasonably implemented.

2
  • 3
    The new way is Objects.equals(Object a, Object b)
    – tmin
    Commented Jul 10, 2015 at 18:02
  • 1
    return (a == null) ? (a == b) : a.equals(b); just seems so much more readable than what you have there (even if it calls equals for the same object). Commented Sep 12, 2017 at 19:16
5
public static boolean equals(Object object1, Object object2) {
    if (object1 == null || object2 == null) {
        return object1 == object2;
    }
    return object1.equals(object2);
}
4

If you are worried about NullPointerExceptions you could just test equality like:

if (obj1 != null && obj1.equals(obj2)) { ... }

The general contract of equals() is that a non-null object should never be equal to a null reference, and that the equals() method should return false if you are comparing an object to a null reference (and not throw a NPE).

4
  • 3
    I use that logic in other scenarios, but here I specifically want two nulls to be considered equal (and thus to execute the true clause). To do this inline would be pretty verbose: if ((obj1 == null && obj2 == null) || (obj1 != null && obj1.equals(obj2))) { ... }
    – dcstraw
    Commented Sep 9, 2009 at 21:02
  • 1
    This is one of those constructs (like checking a string for null and empty or closing a stream without caring about an IOException) that is hard on the eyes and for which commons-lang has a solution for.
    – SingleShot
    Commented Sep 9, 2009 at 21:02
  • I agree with SingleShot and I use commons-lang often for things such as this.
    – matt b
    Commented Sep 9, 2009 at 21:08
  • In my application, I consider to null objects to be equal, which is a case this pattern would reject. Commented Feb 15, 2012 at 22:53
2

Whenever I come across a need and think "this is so common Java must have it" but find it doesn't, I check the Jakarta Commons project. It almost always has it. A quick search of the commons-lang API (which has the most basic of common utilities) shows an equals() method that provides what you want.

1

Jakarta Commons Lang API has what you are looking for ObjectUtils.equals(Object,Object)

0

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