Класс Object
Корень иерархии классов
У всех классов Java есть общая точка в иерархии — java.lang.Object.
Сам Object находится на вершине, а любой другой класс
прямо или косвенно наследуется от него.
Для обычного объявления класса вида class User {}
без явного extends непосредственным родителем становится
Object.
Поэтому методы Object доступны объектам самых разных классов.
Это общий минимальный набор поведения, который есть у любого объекта независимо от того,
какую предметную модель он представляет.
Object как общий тип
Раз Object — общий предок, переменная этого типа может хранить
ссылку на объект любого класса. Это обычное применение уже знакомого полиморфизма:
тип ссылки более общий, а сам объект сохраняет свой реальный класс.
class User {
}
Object value = new User();
System.out.println(value.getClass().getSimpleName()); // User
Здесь переменная имеет тип Object, но внутри по-прежнему находится
объект User. Через такую переменную напрямую доступны только те методы,
которые известны типу Object. Методы самого
User через неё вызвать нельзя.
Массивы тоже являются объектами, поэтому ссылку на массив можно сохранить в переменной
типа Object. А вот примитивные типы вроде
int в иерархию классов не входят.
Что Object даёт каждому объекту
В Object определены методы, которые решают несколько базовых задач:
-
getClass()возвращает класс объекта во время выполнения; -
equals(),hashCode()иtoString()задают стандартные точки расширения для сравнения, хеширования и текстового представления объекта; -
clone()предоставляет базовый механизм копирования объектов; -
wait(),notify()иnotifyAll()связаны с монитором объекта и низкоуровневой координацией потоков.
Сейчас важно увидеть общую картину, а не запоминать контракты всех этих методов.
equals(), hashCode()
и toString() мы подробно разберём в следующей теме,
а методы ожидания и уведомления понадобятся позже при изучении многопоточности.
finalize() для освобождения ресурсов.
В Java 25 этот метод устарел и помечен на удаление. В современном коде управление ресурсами
строят другими способами, поэтому finalize() стоит воспринимать
как наследие старого API, а не как инструмент для нового кода.
Зачем нужен общий предок
Object позволяет Java договориться о базовом поведении для любых объектов.
Благодаря этому совершенно разные классы имеют общие методы и могут использоваться там,
где требуется самый общий объектный тип.
При этом Object не заменяет более точные типы.
Если коду нужен именно User, лучше и объявить переменную как
User. Тип Object полезен тогда,
когда действительно важно работать с объектами разных классов через общий контракт.