Compare two objects with a check for null
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).
Related videos on Youtube
dcstraw
Updated on September 13, 2020Comments
-
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 over 14 yearsI 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 over 14 yearsThis 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 over 14 yearsI agree with SingleShot and I use commons-lang often for things such as this.
-
dcstraw over 14 yearsYes, 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 over 14 yearsI 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 over 14 yearsAgreed. Using Object is better in this case.
-
Steve Kuo over 14 yearsGenerics are useless in this case.
-
Edward Falk over 12 yearsIn my application, I consider to null objects to be equal, which is a case this pattern would reject.
-
tmin almost 9 yearsThe new way is
Objects.equals(Object a, Object b)
-
Edward Falk almost 9 yearsWell, 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 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 almost 9 yearsYes, 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 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 about 3 yearsIt fails for complex objects and hence not very useful.