Все это может создать немало проблем для программистов, особенно для программистов на языке С++, так как они могут спутать метод finalize() с деструктором языка С++ — функцией, всегда вызываемой перед разрушением объекта. Но здесь очень важно понять разницу между Java и С++, поскольку в С++ объекты разрушаются всегда (в правильно написанной программе), в то время как в Java объекты удаляются сборщиком мусора не во всех случаях. Другими словами:
ВНИМАНИЕ-:-
1. Ваши объекты могут быть и не переданы сборщику мусора.
2. Сборка мусора не является удалением.
Если программа завершает свою работу и сборщик мусора не удалил ни одного объекта и не освободил занимаемую память, то эта память будет возвращена операционной системе после завершения работы программы. Это хорошо, так как сборка мусора сопровождается весомыми издержками, и если сборщик не используется, то, соответственно, эти издержки не проявляются.
Для чего нужен метод finalize()?
Итак, если метод finalize() не стоит использовать для проведения стандартных операций завершения, то для чего же он нужен? Запомните третье правило:
ВНИМАНИЕ -
3. Процесс сборки мусора относится только к памяти.
Единственная причина существования сборщика мусора — освобождение памяти, которая перестала использоваться вашей программой. Поэтому все действия, так или иначе связанные со сбором мусора, особенно те, что записаны в методе finalize(), должны относиться к управлению и освобождению памяти.
Но значит ли это, что если ваш объект содержит другие объекты, то в finalize() они должны явно удаляться? Нет — сборщик мусора займется освобождением памяти и удалением объектов вне зависимости от способа их создания. Получается, что использование метода finalize() ограничено особыми случаями, в которых ваш объект размещается в памяти необычным способом, не связанным с прямым созданием экземпляра. Но, если в Java все является объектом, как же тогда такие особые случаи происходят?
Похоже, что поддержка метода finalize() была введена в язык, чтобы сделать возможными операции с памятью в стиле С, с привлечением нестандартных механизмов выделения памяти. Это может произойти в основном при использовании методов, предоставляющих способ вызова He-Java-кода из программы на Java. С и С++ пока являются единственными поддерживаемыми языками, но, так как для них таких ограничений нет, в действительности программа Java может вызвать любую процедуру или функцию на любом языке. Во внешнем коде можно выделить память вызовом функций С, относящихся к семейству malloc(). Если не воспользоваться затем функцией free(), произойдет «утечка» памяти. Конечно, функция free() тоже принадлежит к С и С++, поэтому придется в методе finalize() провести вызов еще одного «внешнего» метода.
После прочтения этого абзаца у вас, скорее всего, сложилось мнение, что метод finalize() используется нечасто>11. И правда, это не то место, где следует проводить рутинные операции очистки. Но где же тогда эти обычные операции будут уместны?
Очистка — ваш долг
Для очистки объекта его пользователю нужно вызвать соответствующий метод в той точке, где эти завершающие действия по откреплению и должны осуществляться. Звучит просто, но немного протйворечит традиционным представлениям о деструкторах С++. В этом языке все объекты