What is the difference between == and .equals() in Java?

Java code on screen
Published on April 5, 2026
#Java #InterviewQuestions #Operators #Comparison

Understanding the difference between == and .equals() is crucial for Java developers. While both are used for comparison, they serve different purposes and have distinct behaviors.

Pro Tip: Using == for object comparison is a common mistake that can lead to unexpected results. Always use .equals() for comparing object contents.

The Interview Question

"What is the difference between == and .equals() in Java?"

Short Answer

In Java, the == operator compares whether two references point to the same object in memory (reference equality), while the .equals() method tests whether the contents or values of objects are the same (content equality).

For primitive data types like int or boolean, == compares their actual values, but for objects, it only checks if they refer to the same memory location. The .equals() method is inherited from the Object class and can be overridden to define custom equality logic for your classes.

Detailed Explanation

Let me break down one of the most common sources of confusion for Java developers. Understanding the difference between == and .equals() is crucial when you're working with Java objects. I've seen this trip up even experienced developers!

The == Operator

The double equals operator (==) in Java has different behaviors depending on what you're comparing:

  • For primitive types (int, char, boolean, etc.): == compares the actual values, checking if they are identical.
  • For reference types (Objects): == compares memory addresses, checking if both references point to the exact same object instance in memory.
Note

Even if two objects have exactly the same content (same property values), == will return false if they are separate instances occupying different memory locations. This is a common gotcha in Java programming!

The .equals() Method

The .equals() method is defined in the Object class, which every Java class inherits from. By default, its implementation behaves exactly like the == operator, checking for reference equality. However, many classes override this method to provide more meaningful comparisons:

  • String: Overrides .equals() to compare the sequence of characters
  • Integer, Long, etc.: Compare the numeric values they represent
  • ArrayList, HashMap, etc.: Compare their contents
Best Practice

When implementing .equals() for your custom class, remember to follow these principles:

  • Reflexivity: an object must equal itself
  • Symmetry: if a.equals(b) then b.equals(a)
  • Transitivity: if a.equals(b) and b.equals(c), then a.equals(c)
  • Consistency: repeated calls should return the same result
  • Null comparison: comparing with null should return false

Code Example

Let me show you a real-world example that demonstrates the difference between == and .equals():

public class EqualityExample {
    public static void main(String[] args) {
        // Primitive types comparison using ==
        int num1 = 5;
        int num2 = 5;
        System.out.println("Primitive comparison (num1 == num2): " + (num1 == num2));  // true

        // Reference comparison with == for objects
        String s1 = new String("Hello");
        String s2 = new String("Hello");
        System.out.println("Reference comparison (s1 == s2): " + (s1 == s2));  // false - different objects

        // String interning example
        String s3 = "Hello";
        String s4 = "Hello";
        System.out.println("String literals comparison (s3 == s4): " + (s3 == s4));  // true - same object in string pool

        // Content comparison with .equals()
        System.out.println("Content comparison (s1.equals(s2)): " + s1.equals(s2));  // true - same content

        // Custom object comparison
        Person person1 = new Person("John", 30);
        Person person2 = new Person("John", 30);
        Person person3 = person1;  // Same reference

        System.out.println("person1 == person2: " + (person1 == person2));  // false - different objects
        System.out.println("person1 == person3: " + (person1 == person3));  // true - same object
        System.out.println("person1.equals(person2): " + person1.equals(person2));  // true if properly overridden
    }
}

class Person {
    private String name;
    private int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Properly overriding equals method
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        
        Person person = (Person) obj;
        return age == person.age && 
               (name == null ? person.name == null : name.equals(person.name));
    }
    
    // Always override hashCode when overriding equals
    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }
}

Key Points from the Example

Let's break down what's happening in this code:

  • For primitive types, == compares values and works as you'd expect.
  • For objects created with new, == returns false even with identical content - they're different objects in memory.
  • String literals with the same content refer to the same object in the string pool - a memory optimization in Java.
  • The .equals() method must be properly overridden to compare object contents - otherwise it just does the same as ==.
  • Always override hashCode() when overriding equals() - this is essential for collections like HashMap to work correctly.

Why This Question Matters in Interviews

This question is a favorite among Java interviewers because it reveals so much about your understanding of core Java concepts:

  • Fundamental Java object concepts and memory model
  • The difference between reference equality and content equality
  • Understanding of overriding methods and contracts
  • Common pitfalls in object comparison

Common Pitfalls and Interview Traps

Watch Out!

Interviewers often include these tricky scenarios to test your understanding:

  1. String comparison trap: Using == to compare String objects and getting inconsistent results due to string interning.
  2. Wrapper class comparison confusion: Not understanding autoboxing and how Integer caching works for small values.
  3. Forgetting to override hashCode(): Breaking the contract that equal objects must have equal hash codes.
  4. Incorrect implementation of .equals(): Not checking for null, wrong class, or not ensuring symmetry.

Conclusion

Understanding the difference between == and .equals() is fundamental to writing correct Java code. It's one of those concepts that seems simple on the surface but has many nuances that can impact your application in significant ways.

To sum up what we've learned:

  • Use == for primitive type comparisons and reference identity checks
  • Use .equals() for comparing object contents
  • Always override .equals() and hashCode() together in custom classes
  • Be aware of special cases like string interning and wrapper class caching

Mastering these concepts will not only help you in interviews but also prevent subtle bugs in your applications that might arise from incorrect equality comparisons. I've seen many production issues traced back to misunderstanding this fundamental concept!

Remember, writing robust Java code means understanding not just what your code does, but how Java itself works under the hood.

About Techoral

Techoral provides high-quality tutorials, guides, and solutions for Java developers and tech enthusiasts.

Learn More
Subscribe to Our Newsletter

Get the latest updates and exclusive content delivered to your inbox!