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.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
dcstraw
  • 3,243
  • 3
  • 29
  • 38

7 Answers7

76

Java 7.0 added a new handy class: Objects.

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

icza
  • 389,944
  • 63
  • 907
  • 827
  • 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% – Edward Falk Jul 11 '15 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 Jul 12 '15 at 07: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. – Edward Falk Jul 12 '15 at 18:07
  • It fails for complex objects and hence not very useful. – saran3h May 05 '21 at 09: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.

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
Yishai
  • 90,445
  • 31
  • 189
  • 263
  • 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 Sep 09 '09 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 Sep 09 '09 at 21:24
  • 1
    Agreed. Using Object is better in this case. – dcstraw Sep 09 '09 at 21:36
  • Generics are useless in this case. – Steve Kuo Sep 10 '09 at 03: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.

Edward Falk
  • 9,991
  • 11
  • 77
  • 112
5
public static boolean equals(Object object1, Object object2) {
    if (object1 == null || object2 == null) {
        return object1 == object2;
    }
    return object1.equals(object2);
}
Brad Cupit
  • 6,530
  • 8
  • 55
  • 60
farid_z
  • 1,673
  • 21
  • 11
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).

matt b
  • 138,234
  • 66
  • 282
  • 345
  • 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 Sep 09 '09 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 Sep 09 '09 at 21:02
  • I agree with SingleShot and I use commons-lang often for things such as this. – matt b Sep 09 '09 at 21:08
  • In my application, I consider to null objects to be equal, which is a case this pattern would reject. – Edward Falk Feb 15 '12 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.

SingleShot
  • 18,821
  • 13
  • 71
  • 101
1

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

cjstehno
  • 13,468
  • 4
  • 44
  • 56