Встречается на 68% собеседований по Java

Какие методы в классе Object знаешь

Класс Object в Java является корнем иерархии классов: каждый класс, включая массивы, неявно наследует его методы. Эти методы предоставляют базовую функциональность для всех объектов, такую как сравнение, клонирование, работа с потоками и получение информации о классе. Знание этих методов важно для понимания основ Java и часто проверяется на собеседованиях.

Основные методы класса Object

В классе Object определено девять методов (без учета перегруженных версий wait). Рассмотрим каждый из них.

  • equals(Object obj) — определяет логическое равенство объектов. По умолчанию сравнивает ссылки (т.е. this == obj). Обычно переопределяется для сравнения по содержимому. При переопределении необходимо соблюдать контракт: рефлексивность, симметричность, транзитивность, согласованность и сравнение с null должно возвращать false.

  • hashCode() — возвращает целочисленный хеш-код объекта. Используется в хеш-структурах (например, HashMap, HashSet). Контракт: если объекты равны по equals, их хеш-коды должны быть равны. Обратное не обязательно, но желательно для производительности.

  • toString() — возвращает строковое представление объекта. По умолчанию выводит ClassName@hashCode в шестнадцатеричном виде. Переопределяется для более информативного вывода.

  • getClass() — возвращает объект типа Class<?>, который представляет класс данного объекта во время выполнения. Позволяет получить имя класса, модификаторы, методы и т.д. Например, obj.getClass().getName().

  • clone() — создает и возвращает копию объекта. Метод объявлен как protected, поэтому доступен только внутри класса или в подклассах. Для вызова необходимо реализовать интерфейс Cloneable, иначе будет выброшено CloneNotSupportedException. По умолчанию выполняет поверхностное копирование.

  • finalize() — вызывается сборщиком мусора перед уничтожением объекта. Метод устарел (deprecated) начиная с Java 9 и не рекомендуется к использованию из-за непредсказуемости и проблем с производительностью.

  • wait(), wait(long timeout), wait(long timeout, int nanos) — заставляют текущий поток ожидать, пока другой поток не вызовет notify() или notifyAll() для этого объекта. Метод должен вызываться в синхронизированном контексте (внутри synchronized блока или метода). Перегруженные версии позволяют указать максимальное время ожидания в миллисекундах и наносекундах.

  • notify() — пробуждает один из потоков, ожидающих на данном объекте. Выбор потока недетерминирован. Также должен вызываться в синхронизированном контексте.

  • notifyAll() — пробуждает все потоки, ожидающие на данном объекте. Также должен вызываться в синхронизированном контексте.

Пример использования

Рассмотрим пример, демонстрирующий переопределение equals, hashCode и toString:

java
public 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;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && name.equals(person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

Подводные камни и частые ошибки

  • Нарушение контракта equals/hashCode: если переопределить equals, но не hashCode, объекты могут некорректно работать в хеш-коллекциях.
  • Использование finalize(): метод устарел, его использование может привести к утечкам памяти и непредсказуемому поведению. Вместо него применяются try-with-resources или Cleaner.
  • Вызов wait/notify вне синхронизации: приведет к IllegalMonitorStateException.
  • Клонирование: без реализации Cloneable вызов clone() выбросит исключение. Также поверхностное копирование может привести к неожиданным результатам для объектов с ссылочными полями.

Коротко

  • Object — базовый класс для всех Java-объектов, предоставляет 9 методов.
  • Ключевые методы: equals, hashCode, toString, getClass, clone, wait, notify, notifyAll, finalize.
  • При переопределении equals всегда переопределяйте hashCode.
  • wait/notify требуют синхронизации, а finalize устарел и не рекомендуется к использованию.
как отвечать на вопрос
пример собеседования
фреймворки на собеседовании
типичные вопросы junior
интервью вопросы и ответы