Методът за финализиране, интерфейсът с възможност за затваряне и инструкцията за опит с ресурси (Java 7) - 1

„Здрасти, Амиго!“

„Току-що реших да обсъдя метода finalize () с вас.“

„Ако си спомняте, finalize() е специален метод, който се извиква от обект, преди събирачът на отпадъци да го унищожи.“

„Основната цел на този метод е да освободи използвани външни ресурси, различни от Java, чрез затваряне на файлове, I/O потоци и т.н.“

„За съжаление, този метод не отговаря на нашите очаквания. Виртуалната машина на Java може да отложи унищожаването на обект, Howто и извикването на метода за финализиране, толкова дълго, колкото иска. Освен това не гарантира, че този метод ще бъде изобщо се извиква. Има много ситуации, в които не се извиква, всичко в името на «оптимизацията»."

„Имам две препоръки за вас:“

Джошуа Блок е написал добра статия за този метод: връзка
Ще перифразирам кратък откъс:

  1. finalize() може да се използва само в два случая:
    1. За проверка or почистване на ресурси с регистриране.
    2. Когато работите с естествен code, който не е критичен за изтичане на ресурси.
  2. finalize() прави GC 430 пъти по-бавен при почистване на обекти
  3. finalize() може да не бъде извикан
Ако кажа в интервю, че finalize е вредна и опасна патерица, чието само съществуване е объркващо, ще бъда ли прав?

— Е, това оправи деня ми, Ели.

„Java 7 има нов оператор, който заменя метода finalize . Нарича се try-with-resources . Това всъщност не е заместител на finalize , по-скоро е алтернативен подход.“

„Като опит-хващане ли е, но с ресурси?“

„Това е почти като 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 е изпълнен правилно or е имало изключение, блокът finally винаги ще бъде извикан и е възможно да се освободят заетите ресурси там.“

„И така, в Java 7 беше взето решението този подход да стане официален, ето така:“

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

„Този ​​специален оператор try се нарича try-with-resources (подобно на начина, по който колекциите имат алтернатива за call foreach ).“

"Забележете, че след опита има скоби, в които се декларират променливи и се създават обекти. Тези обекти могат да се използват вътре в блока за опит, обозначен с фигурни скоби. Когато блокът за опит приключи с изпълнението, независимо дали е приключил нормално or там беше изключение, методът close() ще бъде извикан за всички обекти, създадени в скобите."

„Колко интересно! Тази нотация е много по-компактна от предишната. Все още не съм сигурен, че я разбирам.“

— Не е толкова трудно, колкото си мислите.

„И така, мога ли да посоча класа на всеки обект в скобите?“

— Да, разбира се, иначе скобите не биха бor от голяма полза.

„И ако трябва да извикам друг метод след излизане от блока try, къде да го поставя?“

„Тук нещата са малко по-фини. Java 7 представя следния интерфейс:“

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

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

„С други думи, трябва да отменя метода close и да напиша code в него, за да «почистя» моя обект, и не мога да посоча друг метод?“

„Да. Но можете да посочите няколко обекта – просто ги отделете с точка и запетая:“

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

„Това е по-добре, но не толкова готино, колкото се надявах.“

"Не е толкова лошо. Ще свикнеш. С времето."