151

In Java I am told that when doing a null check one should use == instead of .equals(). What are the reasons for this?

2
  • 15
    The easiest thing is to try null checking with equals() and see. When you try it will instantly be obvious Commented Dec 21, 2010 at 15:50
  • By the way, a google search with keywords "java null check" (without quotes) gave me as one of the top hits this thread, which has the same info as the answers here. Commented Dec 21, 2010 at 15:53

16 Answers 16

213

They're two completely different things. == compares the object reference, if any, contained by a variable. .equals() checks to see if two objects are equal according to their contract for what equality means. It's entirely possible for two distinct object instances to be "equal" according to their contract. And then there's the minor detail that since equals is a method, if you try to invoke it on a null reference, you'll get a NullPointerException.

For instance:

class Foo {
    private int data;

    Foo(int d) {
        this.data = d;
    }

    @Override
    public boolean equals(Object other) {
        if (other == null || other.getClass() != this.getClass()) {
           return false;
        }
        return ((Foo)other).data == this.data;
    }

    /* In a real class, you'd override `hashCode` here as well */
}

Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances

System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition

Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it

System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything

System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
Sign up to request clarification or add additional context in comments.

7 Comments

do you mean public int data?
@Xepoch: No, I don't generally create public fields (although it doesn't really matter for this example either way). Why?
@T.J. Crowder "They're two completely different things.." in general yes. However, the default implementation of both is the same, if my understanding is correct. Looking at the source code, .equals() basically does an == check. hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…
@Ayush - That's the default in Object, yes. It's overridden by a large number of the JDK classes, though. But the point about isn't about implementation, it's about semantics. (Side note: JDK7 is very out of date.)
@RogerWang - Good question! The answer is that null isn't an object, it's an object reference (a blank one). It's the only object reference we can write literally in code. So Object a = null; Object b = null; means that a == b is true, because both variables contain the same object reference (the single universal blank one).
|
52

In addition to the accepted answer (https://stackoverflow.com/a/4501084/6276704):

Since Java 1.7, if you want to compare two Objects which might be null, I recommend this function:

Objects.equals(onePossibleNull, twoPossibleNull)

java.util.Objects

This class consists of static utility methods for operating on objects. These utilities include null-safe or null-tolerant methods for computing the hash code of an object, returning a string for an object, and comparing two objects.

Since: 1.7

2 Comments

Just to make it more visible for others (see chin90's answer or the JavaDoc): Objects.equals(null, null) will return true - keep that in mind.
Intellij always suggests to use Object.equals() instead, when I use == in my code.
46

if you invoke .equals() on null you will get NullPointerException

So it is always advisble to check nullity before invoking method where ever it applies

if(str!=null && str.equals("hi")){
 //str contains hi
}  

Also See

5 Comments

Your example is generally better written as if ("hi".equals(str)).
@user368186: the point isn't whether the equals method includes a null check. If your object reference is null, then the call someObject.equals(null) will raise a NullPointerException without ever entering the equals method.
@ColinD Agree just demonstrating here
It's always advisable to avoid nulls at all cost, so you don't need null checks at all ;).
You can always use Objects.equals(a, b) It won't raise NullPointerException, but it still depends on the "equal" method of the "a" and "b"
31

In Java 0 or null are simple types and not objects.

The method equals() is not built for simple types. Simple types can be matched with ==.

3 Comments

upvote for the actual answer that is most useful as opposed to the obvious "NullPointerException will be returned" herp derp answer.
For “simple types” hope it’s understood that null is not a primitive type, rather it’s default value for object, and have some interesting facts: geeksforgeeks.org/interesting-facts-about-null-in-java/amp
For the record, you can't have a primitive with a null value, so yes, OP wanted to check null safety of objects and not primitives.
6

Object.equals is null safe, however be aware that if two objects are null, object.equals will return true so be sure to check that the objects you are comparing aren't null (or hold null values) before using object.equals for comparison.

String firstname = null;
String lastname = null;

if(Objects.equals(firstname, lastname)){
    System.out.println("equal!");
} else {
    System.out.println("not equal!");
}

Example snippet above will return equal!

2 Comments

As stated by the JavaDoc (it's always wise to read those): Consequently, if both arguments are null, true is returned. ... :)
I mean... if both are null, they are indeed equal... I think that should be obvious to anybody using Objects.equals()
5
foo.equals(null)

What happens if foo is null?

You get a NullPointerException.

Comments

4

If an Object variable is null, one cannot call an equals() method upon it, thus an object reference check of null is proper.

Comments

2

If you try calling equals on a null object reference, then you'll get a null pointer exception thrown.

Comments

2

According to sources it doesn't matter what to use for default method implementation:

public boolean equals(Object object) {
    return this == object;
}

But you can't be sure about equals in custom class.

1 Comment

It matters, since equals can only return false or cause a NullPointerException (or something different if the overriden equals method is nonsense).
2

If we use=> .equals method

if(obj.equals(null))  

// Which mean null.equals(null) when obj will be null.

When your obj will be null it will throw Null Point Exception.

so we should use ==

if(obj == null)

it will compare the references.

Comments

2

here is an example where str != null but str.equals(null) when using org.json

 JSONObject jsonObj = new JSONObject("{field :null}");
 Object field = jsonObj.get("field");
 System.out.println(field != null);        // => true
 System.out.println( field.equals(null)); //=> true
 System.out.println( field.getClass());  // => org.json.JSONObject$Null




EDIT: here is the org.json.JSONObject$Null class:

/**
 * JSONObject.NULL is equivalent to the value that JavaScript calls null,
 * whilst Java's null is equivalent to the value that JavaScript calls
 * undefined.
 */
private static final class Null {

    /**
     * A Null object is equal to the null value and to itself.
     *
     * @param object
     *            An object to test for nullness.
     * @return true if the object parameter is the JSONObject.NULL object or
     *         null.
     */
    @Override
    public boolean equals(Object object) {
        return object == null || object == this;
    }  
}

4 Comments

The issue here is that field.equals(null) returns true. This breaks usual Java behaviour and is therefore confusing. It should only work for field.equals("null"), at least in my point of view. I don't know why the library developers thought, that this would be good to support.
Btw, your first sentence has a grammar issue and it is unclear what you mean with it. Do you mean "Here is an example where str != null and str.equals(null) return true when using org.json."?
I think that's because the jsonObject contains the "field" key that's why field isn't null, it has a reference which contains the json.org.JSONObject$Null object
Yes, but I wouldn't treat Null like null and would use "null" instead. But I guess they did that to avoid requiring Strings. But even with that lib, field.equals(null) is still almost always an issue :P.
1

Because equal is a function derived from Object class, this function compares items of the class. if you use it with null it will return false cause cause class content is not null. In addition == compares reference to an object.

1 Comment

Well, the result can only be false or NullPointerException (if equals is not overriden to something bad).
0

So I never get confused and avoid problems with this solution:

if(str.trim().length() <=0 ) {
   // is null !
}

2 Comments

If str is null this will be an NPE
Additionally an empty string ("" having length 0) is something entirely different than a null reference (i.e. no string).
0

I have encountered this case last night.
I determine that simply that:

Don't exist equals() method for null
So, you can not invoke an inexistent method if you don't have
-->>> That is reason for why we use == to check null

Comments

0

You code breaks Demeter's law. That's why it's better to refactor the design itself. As a workaround, you can use Optional

   obj = Optional.ofNullable(object1)
    .map(o -> o.getIdObject11())
    .map(o -> o.getIdObject111())
    .map(o -> o.getDescription())
    .orElse("")

above is to check to hierarchy of a object so simply use

Optional.ofNullable(object1) 

if you have only one object to check

Hope this helps !!!!

Comments

-3

You could always do

if (str == null || str.equals(null))

This will first check the object reference and then check the object itself providing the reference isnt null.

6 Comments

if (str == null || str.equals(null) || str.equals(""))
i used your answer and added a check for an empty string! if im not mistaken, null and "" are not the same thing.
Is it not completely redundant to add a 2nd check for null?
@JustinRowe It is not only redundant, it is also very wrong. Please, never do something like x.equals(null).
@Tom, JustinRowe please see my answer above why this isn't redundant nor complete garbage stackoverflow.com/questions/4501061/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.