Метод finalize()
вызывается только тогда, когда объект уничтожается и завершается сборщиком мусора, что происходит в некоторый неопределенный момент времени после отбрасывания последней ссылки на объект. Если объект никогда не освобождается (например, у вас все еще есть ссылка на него), finalize()
никогда не вызывается.
Также имейте в виду, что у вас нет контроля над когда finalize()
вызывается и будет ли он вообще когда-либо вызван. См. общее описание _4 _ а>.
Даже System.gc()
не гарантирует, что сборщик мусора что-либо сделает. Это всего лишь предложение для JVM. См. общее описание _6 _ а>
В общем, если вы пытаетесь манипулировать сборщиком мусора таким образом, чтобы выполнить эти типы проверок, обычно есть более эффективные способы. Это неправильное использование finalize()
и GC.
Например, если вы пытаетесь проверить, истинно ли предполагаемое условие, рассмотрите возможность использования assert
в соответствующих местах (но имейте в виду: assert
не является заменой функционального if
; это просто для самодокументирования и проверки условий, принятых в время проектирования).
Если частью функций более высокого уровня вашего приложения является проверка того, что условие истинно перед выходом, то вы должны явно проверить, что условие истинно перед выходом, например в твоем случае:
public static void main(String[] args)
{
Tank tank=new Tank();
tank.fill();
// check explicitly before terminating
if (!tank.empty())
System.err.println("Warning: Ending with non-empty tank!");
}
Явная проверка дает вам полный контроль над тем, когда это происходит, в дополнение к возможности попытаться исправить ошибку.
Обновление: еще один хороший вариант, который MadProgrammer любезно упомянул в комментариях ниже, - это использовать shutdown hook, если вам это подходит. Это обеспечит чистый способ выхода из кода при завершении работы, если у вашего приложения есть несколько точек выхода, которые вы не можете устранить или контролировать иначе.
Кстати, для более сложных приложений вы найдете стратегии тестирования, такие как модульное тестирование и т. тестирование, чтобы быть частью обычного запуска приложения. Не то чтобы с последним что-то не так, особенно в простых приложениях, но вам может быть интересно узнать об этом для дальнейшего использования.
person
Jason C
schedule
08.11.2013
tank=null
, это должно сработать? Честно говоря, я никогда не использовал деконструкцию в Java. - person Jason Sperske   schedule 09.11.2013Closeable
/AutoCloseable
. См. Эффективная Java, пункт 7: Избегайте финализаторов. - person Robin Krahl   schedule 09.11.2013tank=null
(или установка его на что-то другое; суть в том, чтобы не было оставшихся ссылок на интересующий объект) перед вызовомSystem.gc()
, подтолкнет это к работе. Вам все еще не гарантировано, что сборщик мусора действительно будет работать, когда вы вызываетеgc()
, или что он фактически отбросит объект, или что он вызоветfinalize()
для этого объекта - однако, если вы этого не сделаете установитеtank=null
, вы точно гарантируете, что ничего из этого не произойдет. - person Jason C   schedule 09.11.2013