Compare two objects with a check for null

34,212

Solution 1

Java 7.0 added a new handy class: Objects.

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

Solution 2

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.

Solution 3

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.

Solution 4

public static boolean equals(Object object1, Object object2) {
    if (object1 == null || object2 == null) {
        return object1 == object2;
    }
    return object1.equals(object2);
}

Solution 5

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).

Share:
34,212

Related videos on Youtube

dcstraw
Author by

dcstraw

Updated on September 13, 2020

Comments

  • dcstraw
    dcstraw over 3 years

    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.

  • dcstraw
    dcstraw over 14 years
    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))) { ... }
  • SingleShot
    SingleShot over 14 years
    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.
  • matt b
    matt b over 14 years
    I agree with SingleShot and I use commons-lang often for things such as this.
  • dcstraw
    dcstraw over 14 years
    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.
  • Yishai
    Yishai over 14 years
    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?
  • dcstraw
    dcstraw over 14 years
    Agreed. Using Object is better in this case.
  • Steve Kuo
    Steve Kuo over 14 years
    Generics are useless in this case.
  • Edward Falk
    Edward Falk over 12 years
    In my application, I consider to null objects to be equal, which is a case this pattern would reject.
  • tmin
    tmin almost 9 years
    The new way is Objects.equals(Object a, Object b)
  • Edward Falk
    Edward Falk almost 9 years
    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%
  • icza
    icza almost 9 years
    @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.
  • Edward Falk
    Edward Falk almost 9 years
    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.
  • Bernhard Barker
    Bernhard Barker over 6 years
    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).
  • saran3h
    saran3h about 3 years
    It fails for complex objects and hence not very useful.