JavaRush/Курсы/Java Multithreading/Метод finalize, интерфейс closeable, try-with-resources(j...

Метод finalize, интерфейс closeable, try-with-resources(java7)

Открыта
Метод 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();
}

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

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

Комментарии (126)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
C0N5P1RACY QA Automation Engineer
9 февраля, 13:47
— Что это? — А ты как думаешь, п######а? Это лекция! — Это не лекция — это грёбаная вода. Вы из передачи «Весёлый водник»? Вам она для чего, нальете мне воды? Или споёте песенку? Посчитаете, сколько свечек я задую? Я сюда припёрся, чтобы нормально изучить многопоточку! Ждал нормальной лекции с нормальными мужиками, как полковник Кастер и Джеронимо! Вы про них не слыхали. Вы нацепили на себя передники и льете воду в своих лекциях. Так ведь? Рэдж, они пригнали нам сюда стадо до####ых п#######в Дай мне пройти, ср@нь! Отвали! Пошёл с дороги, урод! Тоже мне, кодеры сраные. Ублюдки хреновы, я шёл на лекцию!!! Как в вестерне. Макаки, вашу мать, только время отняли. Кучу времени отняли!!!
Никита
Уровень 1
1 октября 2025, 16:40
если в чате есть питонисты, то там аналогичная история (как и во многих других аспектах): В Python есть деструкторы классов __del__(), которые можно сказать аналогичны методу finalize() в Java. Нет никаких гарантий, что код деструктора будет выполнен. Поэтому в Python рекомендуется для выполнения кода по освобождению ресурсов использовать контекстный менеджер with (аналог try-with-resources), а в классе всю логику переносить в метод __exit__ (или __aexit__ при поддержки асинхронности).
Anonymous #3585174
Уровень 33
23 сентября 2025, 12:19
Like
No Name
Уровень 22
20 ноября 2024, 15:15
+ лекция в копилке
VAKHANDER
Уровень 32
30 октября 2024, 16:12
30.10.2024
Борис
Уровень 33
24 сентября 2024, 20:04
очень мутно объяснено... "А если мне нужно вызвать другой метод при выходе из блока try, где мне его указать?" Какой "другой" метод?
4el0vek3
Уровень 40
18 августа 2025, 06:45
Любой метод кроме close()...
Бромгексин
Уровень 38
6 августа 2024, 08:39
а что в таком случае нужно будет нужно написать в методе close() ??? типо просто так ты своему объекту не скажешь закрыться
Anemon
Уровень 13
Expert
16 ноября 2024, 10:59
Тебе, как создателю объекта, виднее как ему правильно закрываться. Обычно объекты не надо закрывать, но нужно закрывать такие вещи как файлы, некоторые потоки и прочее. Главное помнить об этом, ты туда можешь что угодно впихнуть в качестве метода close()
Максим Li Backend Developer
18 мая 2024, 11:31
18.05.2024
YUREC
Уровень 36
23 марта 2024, 21:16
Эта лекция очень бы была кстати в разделе синктакс на 16 уровне, хотя try with resourses на том уровне объяснено лучше других тем.
Ислам
Уровень 33
20 февраля 2024, 23:53
Полезно