How to prevent null check before equals
Asked Answered
P

9

21

I find stuff like this rather annoying and ugly in equals methods:

if (field == null)
{
    if (other.field != null)
        return false;
}
else if ( ! field.equals(other.field))
    return false;

In C# I could've done this:

if( ! Object.Equals(field, other.field))
    return false;

Is there something similar in Java, or what is the preferred way to do this kind if thing?

Peerage answered 25/10, 2011 at 13:23 Comment(2)
I think you will find this thread useful: #272026Denisdenise
Interesting, sure. Useful... personally it mostly just raised more questions :pPeerage
H
25

Use commons-lang:

org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2)

Source code:

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

From Apache

http://commons.apache.org/lang/

That's about equivalent to what you do in C#

Hedge answered 25/10, 2011 at 13:27 Comment(9)
And if you impor that method statically (import static org.apache.commons.lang.ObjectUtils.equals;) then you can simply write equals(a,b) in your codeRudderpost
Awesome. Didn't know about that class! The ObjectUtils.hashCode was also brilliant.Peerage
@ÓscarLópez: You can't do that. The compiler won't like it (because of the collision with Object.equals(Object)). That's where Guava's equal() method is better suitedHedge
@Svish: I personally like apache commons. But do also have a look at Google Guava as suggested by NimChimpsky here: #7890433Hedge
Just discovered they have a EqualsBuilder and HashCodeBuilder in there too. Might just start using those...Peerage
@Stefan, maybe I'm missing something, but my Eclipse compiler will complainHedge
@Lukas Sorry i was too hasty it does indeed complain but I dont understand tho why the compiler wont let you do that after all they have different signatures. Especially since it does not have the problem with static and non static methods with the same name within a class. And i think i actually ran into that problem myself but forgot.Somerset
@Stefan: I somewhere read the reason for this in the JLS, but I forgot... Let's ask a question on Stack Overflow :)Hedge
@Stefan: here's the question: #7891353Hedge
M
49

Java 7 offers java.util.Objects.equals.

Malefaction answered 25/10, 2011 at 14:55 Comment(3)
This is the "new" recommended way to do this. @Peerage , if you can change the accepted answer for future viewers... :)Distrain
NOTE: For Android, this method requires minimum API >= 19.Sumikosumma
yes, this method helps avoid NullPointerException. Note that Object.equals(null, null) returns true.Salot
H
25

Use commons-lang:

org.apache.commons.lang.ObjectUtils.equals(Object object1, Object object2)

Source code:

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

From Apache

http://commons.apache.org/lang/

That's about equivalent to what you do in C#

Hedge answered 25/10, 2011 at 13:27 Comment(9)
And if you impor that method statically (import static org.apache.commons.lang.ObjectUtils.equals;) then you can simply write equals(a,b) in your codeRudderpost
Awesome. Didn't know about that class! The ObjectUtils.hashCode was also brilliant.Peerage
@ÓscarLópez: You can't do that. The compiler won't like it (because of the collision with Object.equals(Object)). That's where Guava's equal() method is better suitedHedge
@Svish: I personally like apache commons. But do also have a look at Google Guava as suggested by NimChimpsky here: #7890433Hedge
Just discovered they have a EqualsBuilder and HashCodeBuilder in there too. Might just start using those...Peerage
@Stefan, maybe I'm missing something, but my Eclipse compiler will complainHedge
@Lukas Sorry i was too hasty it does indeed complain but I dont understand tho why the compiler wont let you do that after all they have different signatures. Especially since it does not have the problem with static and non static methods with the same name within a class. And i think i actually ran into that problem myself but forgot.Somerset
@Stefan: I somewhere read the reason for this in the JLS, but I forgot... Let's ask a question on Stack Overflow :)Hedge
@Stefan: here's the question: #7891353Hedge
I
5

Guava equal which does this :

public static boolean equal(@Nullable Object a, @Nullable Object b) {
    return a == b || (a != null && a.equals(b));
  }

or null object pattern

Guava also has the somewhat related comparison chain and a load of other goodies.

Inexecution answered 25/10, 2011 at 13:29 Comment(1)
The nice thing about their calling the method equal and not equals (like commons-lang) is the fact that it can be used in static imports...Hedge
M
4

I would write it this way:

return field != null && other.field != null && field.equals(other.field);

which is not as elegant as the C# code line, but much shorter then the if tree you posted.

Maisey answered 25/10, 2011 at 13:27 Comment(2)
Yeah, if it was only one field that could be a solution. Problem is when the object has several fields to check.Peerage
But what if the function has do something afterwards if the result is true?Ergograph
M
2

I accept all answers technically. Practically I will not use any of them in code I have under control because all provided solutions are working around the core problem: null-values. KEEP YOUR CORE MODEL FREE FROM NULL VALUES, and the question is obsolete in this case.

At system borders like third party libraries one has to deal with null values sometimes. They should converted into meaningful values for the core model. There the given solutions are helpful.

Even if Oracle recommends the equals-Methods to be null-safe, think about that: Once you accept null values your model it is getting fragile. The equals-method will not be the last method where you will check for null. You have to manage null-checks in your method call hierarchy. Methods may not be reusable out of the box anymore. Soon, every parameter will be checked for null.

I saw both sides:

On one side code full of null checks, methods that trust not a single parameter anymore and developers that are afraid to forget a null check.

On the other side code with full expressive statements that make clear assertions to have full functioning objects that can be used without fear of NullPointerExceptions.

Meader answered 23/7, 2015 at 19:33 Comment(0)
D
1

As part of the Project Coin, there was a proposal for adding a series of null-safe operators to Java. Sadly, they didn't make it into Java 7, maybe they'll appear in Java 8. Here is the general idea of how they would work

Democrat answered 25/10, 2011 at 13:32 Comment(0)
M
1

Actually everyone follows there own way to do this and also i would like to introduce groovy here.

There is one way

field == null ? false : true; // So basically it will return true when it is not null.

In groovy there is null safe operator for objects. Lets take an example for class

A { 
 String name = "test1"
String surName = "test2"

public String returnName() {

 return name + surName
}

}

A a = null a?.name // Mentioned operator ? will actually check whether a is null or not. then it will invoke name.

Note: i didn't applied semi colon in code as this is not require in groovy.

Mid answered 6/8, 2015 at 6:39 Comment(0)
C
0

String.valueOf() will solve some of those problems if the toString is implemented for your classes. It will spit out the toString() answer or "null" if the pointer is null.

Cherlynchernow answered 25/10, 2011 at 13:26 Comment(4)
That depends whether you want a field value of null to equal one with value "null". I would say in most cases that's not desirable. It also depends on your toString matching exactly what's required for equality matching... and it's also likely to be rather slower...Crackle
I understand why SQL says that null != null, but I don't always agree with that approach. Frequently, when I'm implementing equals, I'm OK with null == null. I agree with the speed comment, but the author wanted to avoid null checking, so I was answering the question.Cherlynchernow
I'm not talking about null == null. I'm talking about null == "null".Crackle
If I was needing this for creating strings, then yes :pPeerage
C
0

Use == operator when you are checking for object references, if both the references refers same object it will return true. Otherwise if you are looking for object content then go with .equals method of objects.

So null means it doesn't have any memory location given in heap. So it can be simply checked with '==' operator.

Centrosphere answered 23/7, 2015 at 19:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.