Java.Core.Rules for overriding the Object.equals() method.

1. Follow the equals() Contract

A correct equals() method must satisfy the following contract rules:

Reflexivity

An object must be equal to itself.

Person p = new Person("Alice", 25);
assert p.equals(p); // true

Symmetry

If a.equals(b), then b.equals(a) must also be true.

Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
assert p1.equals(p2) == p2.equals(p1); // true

Transitivity

If a.equals(b) and b.equals(c), then a.equals(c) must be true.

Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
Person p3 = new Person("Alice", 25);
assert p1.equals(p2) && p2.equals(p3) && p1.equals(p3); // true

Consistency

Multiple calls to equals() must return the same result unless the object’s state changes.

Person p1 = new Person("Alice", 25);
Person p2 = new Person("Alice", 25);
assert p1.equals(p2); // true
assert p1.equals(p2); // true (even if called multiple times)

Null Handling

equals(null) must always return false and should not throw an exception.

Person p = new Person("Alice", 25);
assert !p.equals(null); // false

2. Use the @Override Annotation

Always mark the method with @Override to ensure you are correctly overriding equals() from Object.

@Override
public boolean equals(Object obj) { ... }

3. Check for Reference Equality First (this == obj)

Before performing field comparisons, check if the references are the same. This is an optimization that improves performance.

if (this == obj) return true; // Same memory reference

4. Check for null and Ensure Type Matching

  • If obj is null, return false immediately.
  • Ensure the class types match to avoid ClassCastException.
if (obj == null || getClass() != obj.getClass()) return false;

🔹 Alternative:
Some implementations allow instanceof instead of getClass(), but this can break symmetry in inheritance.


5. Cast and Compare Significant Fields

After checking type compatibility, cast obj to the correct type and compare important fields.

Person person = (Person) obj;
return this.age == person.age && Objects.equals(this.name, person.name);

🔹 Use Objects.equals() instead of == for object fields to avoid NullPointerException:

return Objects.equals(this.name, person.name);

6. Ensure equals() is Consistent with hashCode()

  • If two objects are equal (equals() returns true), they must have the same hashCode().
  • Otherwise, hash-based collections (like HashSet and HashMap) may not work correctly.
@Override
public int hashCode() {
    return Objects.hash(name, age);
}

Example: Correctly Overriding equals()

import java.util.Objects;

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;  // Rule 3: Self-check
        if (obj == null || getClass() != obj.getClass()) return false; // Rule 4: Type check

        Person person = (Person) obj;
        return age == person.age && Objects.equals(name, person.name); // Rule 5: Compare fields
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age); // Rule 6: Keep consistent with equals()
    }
}

Common Mistakes to Avoid

🚫 Forgetting to override hashCode() when overriding equals()
✅ Always override hashCode() to maintain consistency.

🚫 Using == to compare object fields
✅ Use .equals() or Objects.equals() for objects.

🚫 Allowing equals() to throw exceptions
equals(null) should always return false, not throw an exception.

🚫 Using instanceof instead of getClass() in some cases
instanceof may break symmetry in inheritance.


Final Summary

Follow the equivalence relation rules (Reflexivity, Symmetry, Transitivity, Consistency, Null Handling).
Optimize performance by checking this == obj first.
Ensure type safety using getClass() or instanceof carefully.
Use Objects.equals() to avoid NullPointerException.
Ensure hashCode() is overridden to match equals().

By following these rules, your overridden equals() method will be correct, efficient, and compatible with Java collections. 🚀

This entry was posted in Без рубрики. Bookmark the permalink.

Leave a Reply

Your email address will not be published.