Метод finalize

Модуль 2. Java Core
9 уровень , 4 лекция
Открыта
Метод finalize, интерфейс closeable, try-with-resources(java7) - 1

— Привет, Амиго!

Я тут решила с тобой еще раз обсудить метод finalize().

Если ты помнишь, то finalize() – это специальный метод, который вызывается у объекта перед тем, как
сборщик мусора его уничтожит.

Основная цель этого метода – освободить используемые внешние не-Java ресурсы: закрыть файлы, потоки ввода-вывода и т.п.

К сожалению, этот метод не оправдывает возложенных на него надежд. Java-машина может отложить уничтожение объекта, как и вызов метода finalize на сколько угодно. Более того, она вообще не гарантирует, что этот метод будет вызван. В куче ситуаций ради «оптимизации» он не вызывается.

Приведу тебе две цитаты:

У Джошуа Блоха хорошо написано об этом методе: link
Краткая выдержка:

  1. finalize() можно использовать только в двух случаях:
    1. Проверка/подчистка ресурсов с логированием.
    2. При работе с нативным кодом, который не критичен к утечке ресурсов.
  2. finalize() замедляет работу GC по очистке объекта в 430 раз
  3. finalize() может быть не вызван
Если я на собеседовании скажу, что finalize — это вредный и опасный костыль, который своим существованием сбивает с толку, то буду прав?

— М-да, обрадовала ты меня, Элли.

— На замену метода finalize в Java 7 появилась новая конструкция. Называется она – try-with-resources. Это не совсем замена finalize – скорее альтернативный подход.

— Как try-catch, только с ресурсами?

— Почти как try-catch. Дело в том, что в отличие от метода finalize(), блок finally из конструкции try-catch-finally вызывается всегда. Этим и пользовались программисты, когда нужно было гарантированно освободить ресурсы, закрыть потоки и т.д.
Пример:

InputStream is = null;
try
{
 is = new FileInputStream("c:/file.txt");
 is.read(…);
}
finally
{
 if (is != null)
 is.close();
}

Независимо от того, нормально ли отработал блок try, или там возникло исключение, блок finally вызовется всегда, и там можно будет освободить занятые ресурсы.

Поэтому в Java 7 этот подход решили сделать официальным, и вот что из этого вышло:

try(InputStream is = new FileInputStream("c:/file.txt"))
{
 is.read(…);
}

Это специальная конструкция try, называемая try-with-resources (так же как и второй for для коллекций называется foreach).

Обрати внимание – после try следуют круглые скобки, где объявляются переменные и создаются объекты. Эти объекты можно использовать внутри блока try, обозначенного скобками {}. Когда выполнение команд блока try закончится, независимо от того – нормально оно закончилось или было исключение, для объекта, созданного внутри круглых скобок (), будет вызван метод close();

— Как интересно. Такая запись гораздо компактнее, чем предыдущая. Понять бы ее еще.

— Все не так сложно, как ты думаешь.

— А я могу указывать в круглых скобках объекты своих классов?

— Да, конечно, иначе от этих скобок было бы мало пользы.

— А если мне нужно вызвать другой метод при выходе из блока try, где мне его указать?

— Тут все немного тоньше. В Java 7 появился такой интерфейс:

public interface AutoCloseable
{
 void close() throws Exception;
}

Ты можешь унаследовать свой класс от такого интерфейса. И тогда его объекты можно будет использовать внутри try-with-resources. Только объекты такого типа можно использовать внутри круглых скобок try-with-resources для «автоматического закрытия».

— Т.е. мне нужно будет переопределить метод close и написать в нем код по «очистке» моего объекта, а указать другой метод нельзя?

— Ага. Зато можно указывать несколько объектов, разделив их точкой с запятой:

try(
InputStream is = new FileInputStream("c:/file.txt");
OutputStream os = new FileOutputStream("c:/output.txt")
)
{
 is.read(…);
 os.write(…);
}

— Уже лучше, но не так круто, как я надеялся.

— Все не так плохо, ты привыкнешь. Со временем.

Комментарии (12)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Руслан Уровень 48
3 октября 2025
мега сраная задача с методом finalize ведь идея банально ничего не дает с ним сделать
Георгий Уровень 68
12 февраля 2026
Решать только на сайте, в IDEA не получится
Anton Petrov Уровень 38
27 июня 2026
Да ладна, норм задача. Идея хавает)
Andrei A. Уровень 115
23 мая 2025
"У Джошуа Блоха хорошо написано об этом методе: link" ссылка не открывается http://www.informit.com/articles/article.aspx?p=1216151&seqNum=7
Дмитрий Уровень 115 Expert
10 июля 2024
— Т.е. мне нужно будет переопределить метод close и написать в нем код по «очистке» моего объекта, а указать другой метод нельзя? — Ага. Зато можно указывать несколько объектов, разделив их точкой с запятой: что "АГА"??????
Андрей Уровень 5
18 декабря 2024
АХАХАХАХА
9 октября 2023
Уже второй раз Амиго задает вопрос, а его игнорят. Обидно за железного приятеля
Anton Petrov Уровень 38
27 июня 2026
Как экспертом стать Уровня 1?
Misha Saharin Уровень 111 Expert
2 марта 2023
Важно:) никогда finalize не использовать. всегда, по возможности, стремится использовать конструкцию try-with-resources. всегда будет вызван метод close() если твой объект от interface AutoCloseable. тебе нужно будет переопределить метод close и написать в нем код по «очистке» объекта.
Ярослав Уровень 48 Expert
26 октября 2022
Метод finalize "вредный и опасный костыль", да и вообще он уже не актуален, так как вместо него придумали более удобный, "альтернативный подход". Показывать пример в лекции, как он вызывается и работает, мы соответственно не будем. Но запихнём в последнюю задачу, вместе с ещё не изученными методами sql, что бы ты не забывал насколько сильно подача материала может быть абсурдной и ленивой.
Евгений Уровень 109 Expert
24 июня 2024
👍
Владимир Уровень 48 Expert
5 мая 2022

— А если мне нужно вызвать другой метод при выходе из блока try, где мне его указать?
Что-то не понимаю в чём здесь проблема, ведь можно использовать блок finally в try-with-resources.