Что означает понятие «два эквивалентных объекта» в Java?

«Что означает понятие «два эквивалентных объекта» в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Java два объекта считаются эквивалентными, если они логически равны по своему содержимому или состоянию, даже если это физически разные экземпляры в памяти (т.е. a == b возвращает false).

Механизм определения: Логическая эквивалентность определяется методом equals(Object obj). По умолчанию (в классе Object) он сравнивает ссылки (==). Для сравнения по содержимому метод необходимо переопределить.

Пример переопределения equals() и hashCode():

import java.util.Objects;

class Person {
    private final String name;
    private final int age;

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

    @Override
    public boolean equals(Object o) {
        // 1. Проверка ссылки
        if (this == o) return true;
        // 2. Проверка типа
        if (o == null || getClass() != o.getClass()) return false;
        // 3. Приведение типа и сравнение полей
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        // Генерация хэш-кода на основе тех же полей, что и в equals()
        return Objects.hash(name, age);
    }
}

// Использование:
Person p1 = new Person("Alice", 30);
Person p2 = new Person("Alice", 30);
System.out.println(p1.equals(p2)); // true (объекты эквивалентны)
System.out.println(p1 == p2);      // false (это разные экземпляры)

Критически важное правило:

  • Всегда переопределяйте hashCode() вместе с equals(). Контракт объектов требует: если a.equals(b) == true, то a.hashCode() должен быть равен b.hashCode(). Нарушение этого правила приведёт к некорректной работе с HashMap, HashSet и другими хэш-коллекциями.