JavaRush /Курси /Модуль 2. Java Core /Метод finalize, інтерфейс closeable, try-with-resources(j...

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

Модуль 2. Java Core
Рівень 9 , Лекція 4
Відкрита

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

Давай ще раз обговоримо метод 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(…);
}

— Вже краще, але не так круто, як я сподівався.

— Все не так погано, ти звикнеш. З часом.

Коментарі (2)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Aleksey Golovin Рівень 55
12 листопада 2025
Тупа перевірка другого завдання. блок finally був повністю закоментований, але перевірку пройшло лише після видалення
Aleksey Golovin Рівень 55
12 листопада 2025
Нащо давати завдання на створення коду з deprecated методами?