我对 finalize 方法有疑问。如果我有许多具有许多继承的类,我如何在应用程序关闭时调用所有 finalize 方法?
4 回答
System.runFinalizersOnExit(true)
,但请注意它已被弃用。如果您依赖这种事情,那么您基本上已经做错了。
finalize()
方法不在应用程序退出时运行。
推荐的方法是使用关闭挂钩。
例如
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// shutdown logic
}
});
关闭挂钩在以下情况下执行:
- 程序正常退出,例如 System.exit
- 用户中断,例如键入 ^C、注销或系统关闭
Java 还提供了一个名为的方法,runFinalizersOnExit()
即@deprecated
. 它已被弃用,原因如下:
它可能导致在其他线程同时操作这些对象时对活动对象调用终结器,从而导致行为不稳定或死锁
本质上,runFinalizersOnExit()
是不安全的。如上所述,使用关闭挂钩。
如果您需要清理内容、关闭日志文件、发送警报或在 Java 虚拟机关闭时采取其他操作,尤其是当有人按下 CTRL+C 并关闭 VM 或发送终止信号时在 Unix/Linux 中,您必须查看ShutdownHook。
关闭挂钩只是一个已初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩并让它们同时运行。当所有钩子都完成后,如果 finalization-on-exit 已启用,它将运行所有未调用的终结器。最后,虚拟机将停止。请注意,在关闭序列期间,守护线程将继续运行,如果通过调用 exit 方法启动关闭,非守护线程也将继续运行。
最好不要依赖 finalize() 来清理 JVM 中的资源。
从Javadoc。
当垃圾收集确定不再有对该对象的引用时,由对象上的垃圾收集器调用。子类覆盖 finalize 方法以释放系统资源或执行其他清理。
编辑:参考这个关于finalize()用法的博客