Философия Java

         

Смертельное состояние


В общем случае вы не можете полагаться на вызов finalize( ), и вы должны создавать другую функцию “очистки” и явно вызывать ее. Это означает, что finalize( ) полезен только для задач очистки памяти, которые большинство программистов чаще всего не используют. Однако есть очень интересное использование finalize( ), при котором не предполагается, что метод вызывается каждый раз. Это проверка состояния смерти [29] объекта.

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

Вот простой пример, который вы можете использовать:

//: c04:DeathCondition.java

// Использование finalize() для обнаружения объекта,

// который не был правильно очищен.

class Book { boolean checkedOut = false; Book(boolean checkOut) { checkedOut = checkOut; } void checkIn() { checkedOut = false; } public void finalize() { if(checkedOut) System.out.println("Error: checked out"); } }

public class DeathCondition { public static void main(String[] args) { Book novel = new Book(true); // Правильная очистка:

novel.checkIn(); // Бросаем ссылку, забываем очистить:

new Book(true); // Форсируем сбор мусора и финализацию:

System.gc(); } } ///:~

Состояние смерти состоит в том, что предполагается, что все объекты Book проверяются перед сборкой мусора, но в main( ) программист не выполняет ни один из объектов. Без finalize( ) с проверкой состояния смерти было бы трудно обнаружить ошибку.

Обратите внимание, что System.gc( ) используется для форсирования финализации (и должно выполнятся во время разработке программы для ускорения отладки). Но даже если это не так, то есть высокая вероятность того, что блуждающий Book будет обязательно обнаружен при повторных запусках программы (имеется в виду, что программа занимает достаточно места, что является причиной запуска сборщика мусора).



Содержание раздела