Since Java 7 you can use the static method java.util.Objects.equals(Object, Object) to perform equals checks on two objects without caring about them being null.

If both objects are null, it will return true, if one is null and the other isn't, it will return false. Otherwise, it will return the result of calling equals on the first object with the second as argument.

Answer from Mark Rotteveel on Stack Overflow
Top answer
1 of 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
2 of 16
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

🌐
Medium
medium.com › @AlexanderObregon › javas-objects-equals-method-explained-3a84c963edfa
Java’s Objects.equals() Method Explained | Medium
5 days ago - Objects.equals(a, b) is functionally the same as the common pattern (a == b) || (a != null && a.equals(b)), but packaged into one call so the null cases are handled without extra conditional code.
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Objects.html
Objects (Java Platform SE 8 )
October 20, 2025 - Consequently, if both arguments are null, true is returned and if exactly one argument is null, false is returned. Otherwise, equality is determined by using the equals method of the first argument.
🌐
JoeHx Blog
joehxblog.com › does-null-equal-null-in-java
Does Null Equal Null in Java? – JoeHx Blog
October 31, 2018 - I can only use the simple equality operator (the double-equals “==”) or some helper methods, such as Objects.equals(Object, Object). Which is what I did. Below is the short but beautiful Java program I wrote: import java.util.Objects; public class Main { public static void main(final String[] args) { System.out.println("true: " + true); System.out.println("false: " + false); System.out.println(); final String string = null; final Number number = null; System.out.println("null == null: " + (null == null)); System.out.println("string == null: " + (string == null)); System.out.println("number
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › system.nullable-1.equals
Nullable .Equals(Object) Method (System) | Microsoft Learn
' If the HasValue property of the current Nullable<T> structure is true and the other argument is not null, equality is determined by passing the other parameter to the Equals method of the underlying value of the current Nullable<T> structure.
Find elsewhere
🌐
DeepSource
deepsource.com › directory › java › issues › JAVA-E0110
`equals` method does not handle null valued operands (JAVA-E0110) ・ Java
equals must always return false if its argument is null. This can lead to the code throwing a NullPointerException when a null value is passed. One property of any non-static method in Java is that the receiver object (this) is always non-null.
🌐
Errorprone
errorprone.info › bugpattern › EqualsNull
EqualsNull
The contract of Object.equals() states that for any non-null reference value x, x.equals(null) should return false. Thus code such as · if (x.equals(null)) { ... } either returns false, or throws a NullPointerException if x is null. The nested block may never execute.
🌐
Educative
educative.io › answers › what-is-objectsequals-in-java
What is Objects.equals in Java?
The method returns true if the objects are equal; otherwise, equals returns false. In the code below, we pass null as an argument to the equals method.
🌐
Microsoft Learn
learn.microsoft.com › en-us › dotnet › api › system.object.equals
Object.Equals Method (System) | Microsoft Learn
It determines whether either objA or objB is null. If so, it returns false. If the two objects do not represent the same object reference and neither is null, it calls objA.Equals(objB) and returns the result.
Top answer
1 of 1
14

First up, yes, you're right that the second null check is redundant. If obj is null then the method will return false on the first check:

    if (!(obj instanceof ArrayOfColumn)) return false;

Of course, that would better be written:

    if (!(obj instanceof ArrayOfColumn)) {
        return false;
    }

But, that's the least of my concerns. The synchronized equals is probably there because other methods are synchronized, but synchronization comes at a cost. Unless you are sure you need it, remove it.

Additionally, synchronized methods are seldom the best solution. It is normally better to have tighter control of your locks so that nobody but you can hold them. That normally means using a private, internal "monitor" for synchronization:

private final Objct lock = new Object();

private boolean equals(Object obj) {
    synchronized(lock) {
        .....
    }
}

Using the private lock prevents other people from hanging your application by using your class as their own monitor. Imagine if your class is called MyClass, and someone does:

 private MyClass instance = new MyClass();

 synchronized(instance) {
     Thread.sleep(10000);
 }

If they did the above, your methods in other threads would never run, and your application would "hang".

Now, abut the __equalsCalc variable. It does nothing useful. It is set, and then cleared, inside the synchronized method, and, as a result, it will never, ever have any value in it that is useful. It is completely redundant and a waste of time.

Oh, and what's with the fully qualified java.lang.Object? Just use Object.

I would rewrite the method as (using the same synchronized method to be compatible with other methods in your class):

public synchronized boolean equals(Object obj) {
    if (!(obj instanceof ArrayOfColumn)) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    ArrayOfColumn other = (ArrayOfColumn) obj;
    if (getColumn() == null) {
        return other.getColumn() == null;
    }
    return other.getColumn() != null && Arrays.equals(column, other.getColumn());
}

Note that you still have a synchronization vulnerability - the other column's column could be changed between checking for whether it's column is null, and using the column in the equals. You could still get null pointer exceptions if someone changes the other column in the middle of your equals. You should consider synchronizing on that other column too:

public synchronized boolean equals(Object obj) {
    if (!(obj instanceof ArrayOfColumn)) {
        return false;
    }
    if (obj == this) {
        return true;
    }
    ArrayOfColumn other = (ArrayOfColumn) obj;
    synchronized(other) {
        if (getColumn() == null) {
            return other.getColumn() == null;
        }
        return other.getColumn() != null && Arrays.equals(column, other.getColumn());
    }
}

Unfortunately, cross-synchronizing like that can lead to deadlocks if you are not careful.

🌐
Medium
medium.com › @thilinajayawardana_85346 › java-string-nullpointerexception-safe-equals-check-404481934e9b
Java String NullPointerException safe equals check | by Thilina Jayawardana | Medium
June 30, 2020 - Thus a NullPointerException. The better way to do it will be like follows. if (theStringIknow.equals(someString)) { System.out.println("Same same"); } In that case, you are always invoking the equals method of a String that you are pretty sure it exists. Usually, it could be a constant or a new String object.
🌐
Reddit
reddit.com › r/csharp › [deleted by user]
Object.ReferenceEquals, != / == null, or "is null"? (and why?)
March 24, 2017 - When used as a conditional,obj is null is equivalent to ReferenceEquals(obj, null), and definitely NOT obj == null. The rest of your advice is also questionable. ... Except for, ya know, I'm right. ... It would seem so, but checking the generated IL, it seems you aren’t. What it does is issue a non-virtual call to Object.Equals.