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


В Java класс Object является корневым суперклассом для всех других классов. Это означает, что каждый класс в Java либо явно, либо неявно наследует Object. Он предоставляет набор базовых методов, которые могут быть переопределены в пользовательских классах для изменения поведения по умолчанию. Методы из Object охватывают базовую функциональность, такую как сравнение объектов, клонирование, получение строки-представления, уведомление потоков и работа с хеш-кодами.

Ниже приведён перечень методов, определённых в классе java.lang.Object, с подробным описанием каждого из них:

🔹 public String toString()

Возвращает строковое представление объекта. По умолчанию возвращает строку вида:

ИмяКласса@ХэшКодВШестнадцатеричномВиде

Переопределяется для:

  • Вывода пользовательской информации об объекте.

  • Удобства отладки.

Пример:

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

🔹 public boolean equals(Object obj)

Сравнивает текущий объект с другим объектом obj.

  • По умолчанию проверяет ссылочное равенство (this == obj).

  • Часто переопределяется для логического сравнения содержимого.

При переопределении рекомендуется также переопределить hashCode().

Пример:

@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Person)) return false;
Person other = (Person) obj;
return this.name.equals(other.name) && this.age == other.age;
}

🔹 public int hashCode()

Возвращает хеш-код объекта. Используется в хеш-таблицах (HashMap, HashSet, Hashtable).

  • По умолчанию связан с адресом объекта в памяти.

  • При переопределении equals() обязательно переопределить hashCode(), чтобы сохранялось правило: если a.equals(b) == true, то a.hashCode() == b.hashCode().

Пример:

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

🔹 protected Object clone() throws CloneNotSupportedException

Создаёт и возвращает копию текущего объекта.

  • Работает, если класс реализует интерфейс Cloneable.

  • По умолчанию создаёт поверхностную копию (shallow copy).

  • Для глубокой копии (deep copy) нужно реализовать вручную.

Пример:

class Person implements Cloneable {
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

🔹 public final Class<?> getClass()

Возвращает объект Class, представляющий тип объекта во время выполнения.

  • Используется для рефлексии (анализ классов во время выполнения).

  • Метод финальный, переопределение невозможно.

Пример:

Person p = new Person();
System.out.println(p.getClass().getName()); // com.example.Person

🔹 public final void wait() throws InterruptedException

Приостанавливает текущий поток до тех пор, пока другой поток не вызовет notify() или notifyAll() на том же объекте.

  • Используется в синхронизации потоков.

  • Должен вызываться внутри синхронизированного блока (иначе будет IllegalMonitorStateException).

Разновидности:

  • wait() — ждет бесконечно.

  • wait(long timeout) — ждет указанное время (в миллисекундах).

  • wait(long timeout, int nanos) — более точная версия.

🔹 public final void notify()

Пробуждает один поток, который ожидает на этом объекте (вызвал wait()).

  • Работает только в синхронизированном контексте.

  • Если несколько потоков ждут, будет разбужен один случайный поток.

🔹 public final void notifyAll()

Пробуждает все потоки, ожидающие на этом объекте.

  • Все пробуждённые потоки будут соревноваться за монитор (блокировку) объекта.

🔹 protected void finalize() throws Throwable (УСТАРЕВШИЙ)

Вызывается сборщиком мусора (GC) перед уничтожением объекта.

  • Использовался для освобождения ресурсов (например, закрытие файлов), но с Java 9 объявлен устаревшим (@Deprecated) и больше не рекомендуется к использованию.

  • Был ненадёжен, неопределён по времени вызова и плохо управлялся.

Современная альтернатива:

Использование try-with-resources и интерфейса AutoCloseable.

🔹 Переопределение и правила

При переопределении equals() и hashCode() следует соблюдать следующие контракты:

Контракт equals():

  1. Рефлексивность: x.equals(x) должно быть true.

  2. Симметричность: x.equals(y) == y.equals(x).

  3. Транзитивность: если x.equals(y) и y.equals(z), то x.equals(z).

  4. Постоянство: многократные вызовы возвращают один и тот же результат (если объект не изменён).

  5. Сравнение с null: x.equals(null) должно быть false.

Контракт hashCode():

  • Если a.equals(b) → a.hashCode() == b.hashCode().

  • Объекты с разным hashCode не обязаны быть неравными, но желательна минимизация коллизий.

🔹 Роль этих методов в коллекциях

Метод Где используется
equals() В List.contains(), Set.contains(), Map.get()
--- ---
hashCode() В HashSet, HashMap, Hashtable
--- ---
toString() При логировании, отладке, выводе объектов
--- ---
clone() При необходимости скопировать объект
--- ---
getClass() При динамическом анализе типов
--- ---
wait()/notify() В низкоуровневой синхронизации потоков, при реализации собственных блокировок
--- ---

🔹 Частые ошибки

  1. Не переопределён hashCode() при переопределённом equals() — приводит к неправильной работе HashMap и HashSet.

  2. Нарушение контракта equals() — несимметричные или нестабильные реализации.

  3. Переопределение clone() без реализации Cloneable — вызовет CloneNotSupportedException.

  4. Вызов wait() или notify() вне synchronized — приведёт к IllegalMonitorStateException.

  5. Использование finalize() — нежелательно из-за проблем с производительностью и надёжностью.

🔹 Пример: реализация пользовательского класса с переопределением

public class Person {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof Person)) return false;
Person other = (Person) obj;
return age == other.age && name.equals(other.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return name + ", " + age + " лет";
}
}

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