本文正在参加「Java主题月 – Java Debug笔记活动」,详情查看<活动链接>
提问:Java中的finalize()
方法在什么时候会被调用?
我创建了一个测试类,当finalize()
方法被调用的时候,会向文件中写入一些东西。但是这个程序并没有被执行,这是为什么呢?
回答一
finailze()
方法在对象即将被垃圾回收时调用。但即使是这个对象已经被视为垃圾,它被回收的时间也无法确定。
请注意,一个对象完全有可能永远不会被垃圾回收,因此永远不会调用finalize()
方法。
- 对象不符合gc条件
当对象一直被引用,并且一直可被访问时发生
- 符合gc条件,但一直没有被垃圾回收
这通常发生在简单的测试程序中。
有一些方法可以让JVM在一些还没有被调用的方法上使用finalize
方法,但这也不是一个好主意,因为这些方法不能保证垃圾回收一定会被执行。
你肯定不能依赖finalize
来完成正确的操作,finalize
只能用于清理资源(通常是非Java资源)。JVM不能保证finalize
方法一定会在某个对象上调用。
回答二
protected void finalize() throws Throwable {}
复制代码
- 每个类都会从
java.lang.Object()
继承finalize()
方法 - 当垃圾收集器确定不再存在该对象的引用时,这个方法将会被调用。
finalize()
本身不会执行任何操作,但是它可以被任意类重写。- 通常用这个方法来关闭非Java资源,比如关闭一个文件。
- 如果重写
finalize()
最好使用try-catch-finally
语句并始终调用super.finalize()
。这是一种安全措施,可确保你不会忘记关闭调用类对象所用的资源。
protected void finalize() throws Throwable {
try {
close(); // close open files
} finally {
super.finalize();
}
}
复制代码
- 垃圾回收期间,任何由
finalize()
引发的异常都会导致停止回收,但是异常会被忽略。 finalize()
不会在一个对象上调用多次。
回答三
一般来说,最好不要依赖finalize()
方法进行任何清理工作。
根据Javadoc描述:
当对象不被任何地方引用时,垃圾收集器将会把这个对象收集起来作为垃圾。
如果一个对象永远可以被访问的话,垃圾回收这种事情就永远不会发生。
而且,垃圾收集器并不能保证在任何特定的时间会执行,除非你需要使用finalize()
做一些特别的事情,否则不要使用这个方法。
文章翻译自Stack Overflow:stackoverflow.com/questions/2…
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END