Difference Between And Equals In Java

6 min read

Difference between == and .equals in Java
Understanding the distinction between the == operator and the .equals() method is fundamental for writing correct Java code, especially when dealing with objects rather than primitive types. While both can be used to test equality, they operate on different levels: == checks reference identity, whereas .equals() (when properly overridden) evaluates logical equivalence. Misusing them leads to subtle bugs that are hard to trace, so grasping when each tool is appropriate is essential for any Java developer.

How the == Operator Works

The == operator in Java is a binary relational operator that compares the values of its two operands. In real terms, for primitive data types (int, char, boolean, double, etc. ) it evaluates whether the actual bit patterns are identical. For reference types (objects, arrays), == compares the memory addresses stored in the reference variables—i.Consider this: e. , it determines whether both references point to the exact same object on the heap.

int a = 5;
int b = 5;
System.out.println(a == b); // true – same primitive value

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false – two distinct objects

String s3 = s1;
System.out.println(s1 == s3); // true – same reference

When dealing with string literals or values retrieved from the string pool, == may return true because the JVM reuses existing instances, but relying on this behavior is fragile and not recommended for logical equality checks.

How the .equals() Method Works

Every class in Java inherits from java.lang.Object, which provides a default implementation of the public boolean equals(Object obj) method. The default version simply uses == under the hood, thus behaving like reference equality. Still, many core classes (such as String, Integer, LocalDate, etc.) override equals() to compare the meaningful state of the objects instead of their memory locations.

Not the most exciting part, but easily the most useful Small thing, real impact..

When you override equals(), you should also override hashCode() to maintain the contract required by hash‑based collections (HashMap, HashSet, etc.). A well‑written equals() method typically follows these steps:

  1. Reference checkif (this == obj) return true;
  2. Null checkif (obj == null) return false;
  3. Type checkif (!(obj instanceof MyClass)) return false; (or use getClass() for stricter equality)
  4. Field comparison – compare each relevant field, using == for primitives and .equals() for references, handling null appropriately.
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return age == person.age &&
           Objects.equals(name, person.name);
}

Key Differences Between == and .equals()

Aspect == Operator .equals() Method
What it compares Reference identity (memory address) for objects; value equality for primitives Logical equality as defined by the class (often field‑by‑field)
Default behavior Same for primitives and objects (value vs. This leads to address) Delegates to == unless overridden
Overrideability Cannot be overridden; it is a language operator Can be overridden to provide custom equality semantics
Null safety Throws NullPointerException if left operand is null and right is a reference (e. g., null == obj is fine, but `obj.

No fluff here — just what actually works Easy to understand, harder to ignore..

When to Use Which

  • Use == when you need to know whether two references point to the exact same object. Typical scenarios include:

    • Checking for null (reference == null).
    • Comparing enum constants (since each enum value is a singleton instance).
    • Optimizing quick identity checks inside equals() or hashCode() implementations.
  • Use .equals() when you care about the logical meaning of the objects. This is the default choice for:

    • Comparing String values.
    • Comparing wrapper classes (Integer, Double, Boolean, etc.).
    • Comparing user‑defined entities where equality is based on business keys or data fields.
    • Working with collections that rely on equals() for containment tests (List.contains(), Set.add(), Map.get()).

Example: Wrapper Classes

Integer a = 127;
Integer b = 127;
System.out.println(a == b);   // true – due to caching of -128..127
System.out.println(a.equals(b)); // true – same value

Integer x = 200;
Integer y = 200;
System.That's why out. println(x == y);   // false – outside cache, two objects
System.In real terms, out. println(x.

Here, `==` can give misleading results outside the cached range, while `.equals()` consistently reflects numeric equality.

## Common Pitfalls  

1. **Assuming `==` works for strings** – Many beginners write `if (str == "literal")` and get unexpected results when the string is created via `new String()` or read from input. Always use `.equals()` (or `Objects.equals()` for null‑safe checks) for string comparison.  

2. **Failing to override `hashCode()` when overriding `equals()`** – This breaks the contract required by hash‑based collections, causing objects to be stored incorrectly or not found at all.  

3. **Using `==` with boxed primitives in loops or caches** – As shown above, reliance on `==` for values outside the integer cache leads to bugs that are hard to reproduce.  

4. **Neglecting null checks in custom `equals()`** – If you forget to test `obj == null`, calling `equals(null)` will throw a `NullPointerException`.  

5. **Using `getClass()` vs `instanceof` incorrectly** – `getClass()` enforces that only objects of the exact same class can be equal, which is appropriate for most value‑based classes. `instanceof` allows subclasses to be considered equal, which may be desirable in some hierarchies but can violate symmetry

if the subclass adds fields or defines equality differently. For most classes, especially immutable value objects, `getClass()` is often the safer choice.

A good custom `equals()` implementation usually follows this pattern:

```java
@Override
public boolean equals(Object obj) {
    if (this == obj) return true;          // same reference
    if (obj == null) return false;         // null is never equal
    if (getClass() != obj.getClass()) return false;

    Person other = (Person) obj;
    return Objects.equals(id, other.id);   // compare meaningful fields
}

And if equals() compares id, then hashCode() should do the same:

@Override
public int hashCode() {
    return Objects.hash(id);
}

For modern Java code, record types can reduce boilerplate because Java automatically generates equals(), hashCode(), and toString() based on the record components:

public record Point(int x, int y) {}

Now two Point records with the same coordinates are logically equal:

Point p1 = new Point(10, 20);
Point p2 = new Point(10, 20);

System.out.println(p1 == p2);      // false
System.out.println(p1.equals(p2)); // true

Rule of Thumb

Use this simple guideline:

  • Use == for identity: “Are these the exact same object?”
  • Use .equals() for equality: “Do these objects represent the same value?”

In everyday Java development, .equals() is the right choice for comparing object contents, especially strings, wrapper values, and domain objects. Reserve == for reference identity checks such as null, enum comparison, or internal optimizations The details matter here..

Conclusion

Understanding the difference between == and .Now, equals() is essential for writing correct Java code. But the == operator checks whether two references point to the same memory location, while . equals() checks whether two objects are logically equivalent according to their implementation.

Most bugs come from using == when logical comparison was intended. Day to day, equals(), override both equals()andhashCode()together, handlenullcarefully, and let tools such as IDEs or records generate equality code when possible. To avoid them, compare object values with.This keeps comparisons predictable and ensures your objects behave correctly in collections and business logic.

Counterintuitive, but true.

Brand New Today

What People Are Reading

More in This Space

More Good Stuff

Thank you for reading about Difference Between And Equals In Java. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home