Почему finalize() признан неудачным механизмом и что использовать вместо него?
finalize не гарантирует ни вызова, ни времени, замедляет сборку (объект переживает лишний цикл) и может «воскресить» объект. Устарел в Java 9, помечен к удалению в Java 18. Ресурсы закрывают try-with-resources, а Cleaner держат только как страховку.
- Финализатор выполняется в одном потоке — очередь может не разгребаться, и память утекает
- Исключение в finalize игнорируется
- Cleaner не воскрешает объект и не тормозит сборку так сильно
А ещё JVM можно запустить с --finalization=disabled и проверить, что ничего не сломалось
Подробно
Перечисли претензии по существу: спецификация не гарантирует, что finalize вообще будет вызван, и уж тем более не говорит когда; работу делает отдельный поток-финализатор, очередь которого может не разгребаться; объект с финализатором переживает лишний цикл сборки, потому что сначала его надо обработать. Добавь, что внутри finalize объект можно случайно воскресить, снова сделав достижимым, а брошенное исключение проглатывается без следа. Правильная замена — детерминированное освобождение: класс реализует AutoCloseable, вызывающий код использует try-with-resources. Cleaner из Java 9 годится только как подстраховка на случай, если close забыли, но не как основной механизм. Метод объявлен устаревшим и подлежит удалению.
Что хотят услышать
- Претензии к finalize.
- try-with-resources как основной механизм.
- Cleaner как запасной.
Частые ошибки
- Предлагать Cleaner как полноценную замену вместо try-with-resources.
- Считать, что finalize гарантированно отработает при завершении JVM.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗finalize вызывается слишком часто — после каждого обращения к объекту
- ✗Его заменил System.gc(), который гарантированно вызывает очистку
- ✓Вызов не гарантирован и тормозит сборку; ресурсы закрывают try-with-resources
- ✗finalize нельзя переопределить в своём классе, поэтому он бесполезен для освобождения внешних ресурсов
Что спросят дальше
- Как правильно реализовать close() у класса с внешним ресурсом?
- Почему Cleaner не должен ссылаться на сам очищаемый объект?
Разбор темы
- GC: корни, достижимость и типы ссылок
GC roots и reachability, strong/soft/weak/phantom-ссылки, Cleaner вместо finalize и утечки через сильные ссылки.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.