Какие типы ссылок существуют в Java и чем они отличаются?

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

Ответ

В Java, помимо обычной сильной ссылки, в пакете java.lang.ref существуют специальные типы ссылок, которые дают Garbage Collector разные степени контроля над временем жизни объекта.

Тип ссылки Класс Когда объект удаляется GC? Основное применение
Сильная (Strong) Object obj = new Object(); Никогда, пока на него есть сильная ссылка. Стандартное создание объектов.
Мягкая (Soft) SoftReference<Object> При нехватке памяти (перед OutOfMemoryError). Реализация кэшей в памяти, которые можно безопасно очистить.
Слабая (Weak) WeakReference<Object> В следующем цикле сборки мусора, независимо от состояния памяти. Хранение метаданных, кэши, где данные можно легко восстановить (напр., WeakHashMap).
Фантомная (Phantom) PhantomReference<Object> После финализации. Ссылка get() всегда возвращает null. Мониторинг точного момента удаления объекта для безопасного освобождения внешних ресурсов (нативная память, файловые дескрипторы).

Ключевые отличия и примеры:

// 1. Strong Reference - объект жив, пока ссылка 'strong' существует.
Object strong = new Object();

// 2. SoftReference - выживает до критической нехватки памяти.
SoftReference<byte[]> softCache = new SoftReference<>(new byte[10_000_000]);
byte[] data = softCache.get(); // Может вернуть null, если GC очистил объект.

// 3. WeakReference - очищается быстро.
WeakReference<Object> weakRef = new WeakReference<>(new Object());
System.gc(); // После этого вызова weakRef.get() с большой вероятностью вернёт null.

// 4. PhantomReference - всегда требует ReferenceQueue, get() == null.
ReferenceQueue<Object> queue = new ReferenceQueue<>();
PhantomReference<Object> phantomRef = new PhantomReference<>(new Object(), queue);
// Используется для логики очистки после удаления объекта.

Почему это важно: Слабые и мягкие ссылки предотвращают утечки памяти, позволяя GC удалять объекты, которые не являются критичными для работы программы.