Как правильно реализовать метод сравнения объектов (equals) в Java?

«Как правильно реализовать метод сравнения объектов (equals) в Java?» — вопрос из категории Основы программирования, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Каноническая реализация equals() в Java:

@Override
public boolean equals(Object obj) {
    // 1. Проверка ссылочного равенства
    if (this == obj) return true;
    // 2. Проверка на null и совпадение класса
    if (obj == null || getClass() != obj.getClass()) return false;

    // 3. Приведение типа и сравнение полей
    MyClass other = (MyClass) obj;
    return Objects.equals(this.name, other.name)
        && this.age == other.age
        && Objects.equals(this.email, other.email);
}

Ключевые шаги и best practices:

  1. Ссылочное равенство: Быстрая проверка if (this == obj).
  2. Проверка типа: Убедиться, что obj не null и имеет тот же класс (getClass()). Использование instanceof допустимо для нефинальных классов, если соблюдается симметричность.
  3. Безопасное сравнение полей: Использовать Objects.equals() для ссылочных типов (обрабатывает null) и == для примитивов.
  4. Согласованность с hashCode(): Всегда переопределяйте hashCode(), если переопределяете equals(), чтобы объекты, признанные равными, имели одинаковый хэш-код.

Современная альтернатива (Java 14+): Используйте record, который автоматически генерирует equals(), hashCode() и toString() на основе компонентов.

public record MyClass(String name, int age, String email) {}