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
Answer from T.J. Crowder 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
2 weeks ago - In this example, attempting to call a.equals(b) results in a NullPointerException because a is null.
🌐
JoeHx Blog
joehxblog.com › does-null-equal-null-in-java
Does Null Equal Null in Java? – JoeHx Blog
October 31, 2018 - Below is the short but beautiful ... final String string = null; final Number number = null; System.out.println("null == null: " + (null == null)); System.out.println("string == null: " + (string == null)); System.out.print...
🌐
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 - public class DemoApplication { final static String theStringIknow = "Hello"; public static void myTestMethod(String someString) { //do not do this if (someString.equals(theStringIknow)) { System.out.println("Same same"); } } public static void main(String[] args) { String testString = null; myTestMethod(testString); } }Exception in thread "main" java.lang.NullPointerException at com.example.demo.DemoApplication.myTestMethod(DemoApplication.java:7) at...
🌐
Errorprone
errorprone.info › bugpattern › EqualsNull
EqualsNull
This check replaces x.equals(null) with x == null, and !x.equals(null) with x != null. If the author intended for x.equals(null) to return true, consider this as fragile code as it breaks the contract of Object.equals(). See Effective Java 3rd Edition §10: Objey the general contract when overriding equals for more details.
🌐
Educative
educative.io › answers › what-is-objectsequals-in-java
What is Objects.equals in Java?
The method should return false, as one of the input objects is null. ... System.out.println("The Objects.equals() method returns '" + equalityCheck + "' when null is passed as the first object.");
Find elsewhere
🌐
Codemia
codemia.io › knowledge-hub › path › compare_two_objects_in_java_with_possible_null_values
Compare two objects in Java with possible null values
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises
🌐
DeepSource
deepsource.com › directory › java › issues › JAVA-E0110
`equals` method does not handle null valued operands (JAVA-E0110) ・ Java
ld throw `NoSuchElementException`JAVA-W0146Map compute methods cannot be used to create null valued entriesJAVA-W1011Audit: Double checked locking is not safeJAVA-E1018Static methods should be accessed using the class instanceJAVA-W1029`equals()` method parameters should not be marked with `@NotNull` or equivalent annotationsJAVA-W1028Basic authorization is a security riskJAVA-S1019Sealed class/interface permitted types need not be listed if they are declared in the same fileJAVA-W1031Boxed Boolean values should not be used in conditional expressionsJAVA-E1054@NoAllocation annotated methods sh
🌐
EqualsVerifier
jqno.nl › equalsverifier › manual › null
Dealing with null - EqualsVerifier
3 weeks ago - For safety, EqualsVerifier requires you to add null checks for non-primitive fields you reference in your equals or hashCode method. If you don’t, you will get the following error message: Non-nullity: equals throws NullPointerException on field o.
🌐
TutorialsPoint
tutorialspoint.com › comparing-strings-with-possible-null-values-in-java
Comparing Strings with (possible) null values in java?
In the same way the equals() method of the object class accepts two String values and returns a boolean value, which is true if both are equal (or, null) and false if not. import java.util.Scanner; public class CompringStrings { public static void main(String args[]) { Scanner sc = new Scanner(System.in); System.out.println("Enter your first string value: "); String str1 = sc.next(); System.out.println("Enter your second string value: "); String str2 = sc.next(); if(str1.equals(str2)) { System.out.println("Both Strings are null or equal"); }else { System.out.println("Both Strings are not equal"); } } } Enter your first string value: null Enter your second string value: null 0 Both Strings are null or equal ·
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.

🌐
Coderanch
coderanch.com › t › 523760 › java › null-null-java
null==something vs something==null in java (Beginning Java forum at Coderanch)
The short answer is that they are the same. The long answer is that this is a remains from the old C days where everything could be treated as a boolean. If you forgot one of the = signs you would get an assignment. With something = null that assignment would succeed and the result would be equal ...
🌐
Baeldung
baeldung.com › home › java › java string › comparing strings in java
Comparing Strings in Java | Baeldung
June 19, 2024 - As the name suggests this method ignores casing in characters while comparing Strings: String string1 = "using equals ignore case"; String string2 = "USING EQUALS IGNORE CASE"; assertThat(string1.equalsIgnoreCase(string2)).isTrue();
🌐
GeeksforGeeks
geeksforgeeks.org › java › program-to-check-if-the-string-is-null-in-java
Program to check if the String is Null in Java - GeeksforGeeks
July 12, 2025 - To check if a string is null in Java, we can use the "==" operator that directly compares the string reference with null. ... The below example demonstrates how to check if a given string is null using the == relational operator.
🌐
TechVidvan
techvidvan.com › tutorials › java-string-equals-method
Java String equals() Method - TechVidvan
March 18, 2024 - Custom Comparison: You can design your own logic for comparing objects based on their characteristics by overriding the equals() function for custom classes. This enables you to perform unique equality checks catered to the needs of your application. Handling Nulls:Calling equals() on a string that might be null is secure.