Зачем нужен метод finalize в Java
Javaметод finalizeосновы Javaсборка мусорауправление памятью
Что проверяют
Знаете ли вы, что этот метод давно объявлен устаревшим, и назовёте ли современную замену. Ответ «для освобождения ресурсов» считается неверным.
Как отвечать
finalize() задумывался как последний шанс освободить ресурсы: сборщик мусора вызывал его перед уничтожением объекта. На практике механизм оказался непригодным и объявлен устаревшим в Java 9, а начиная с Java 18 отключён по умолчанию и подлежит удалению.
Почему от него отказались:
- нет гарантии вызова: объект может так и не собраться, а при завершении программы метод не вызывается вовсе;
- нет гарантии времени: между потерей ссылок и вызовом проходит неопределённый срок, и всё это время файл или соединение остаются занятыми;
- замедляет сборку мусора: объекты с финализатором живут дольше, проходят дополнительный цикл и обрабатываются отдельным потоком;
- воскрешение объекта: внутри метода можно снова сохранить ссылку на себя, что ломает предположения сборщика;
- исключение внутри проглатывается молча.
Чем заменяют:
try-with-resourcesиAutoCloseableэто основной способ: освобождение происходит детерминированно, в конце блока;Cleanerдля страховки на случай, если пользователь класса забыл закрыть ресурс. Он работает через фантомные ссылки и не удерживает объект;- в редких случаях явная ссылочная очередь с фантомными ссылками.
try (var in = Files.newInputStream(path)) {
...
} // закроется здесь, а не когда-нибудьГде спотыкаются
Рассказывают, как правильно писать finalize, вместо того чтобы сказать, что писать его не нужно.
Считают, что метод вызовется при завершении программы.
Путают finalize с finally: первый относится к сборке мусора, второй к обработке исключений.