Finalizers are unpredictable ,often dangerous ,and generally unnecessary.
在Java中,GC会自动回收不可达对象相关的空间,而不需要程序员做相关的工作。对于非内存资源,我们通常使用try-finally语句块进行释放。
finalizer不保证立即执行。
从一个对象编程不可达状态到调用finalizer,这段时间是任意的。
即,对时间敏感的操作不能在finalizer中进行。?
比如对一些资源对象进行close,file descriptor是有限资源,不及时关闭的后果很严重。
(PS:话说AutoCloseable的author也是Josh Bloch。)
哪些finalizer会及时得到执行,这个问题主要依赖于GC算法。
但GC算法在不同的JVM中的表现或多或少会不一样(我做过的项目都是用Hotspot...)。
一个程序可能在开发时运行得不错,而换了个环境可能会无法正常运行。
(比如finalizer的优先级太低,一直没得到回收,回收速度跟不上创建速度。)
不仅不保证finalizer执行的及时性,而且也不保证finalizer执行的可能性。
finalizer有可能根本得不到执行。
比如,很多不可达对象的finalizer尚未得到执行,此时程序被终止。
也不要期待以下方法为finalizer的执行提供保障:
值得一提的是,如果未捕获的异常在finalizer中抛出,这个异常会被无视掉,而且连stack trace都不会打印出来。
另外,finalizer有非常严重的性能损耗,这种东西最好尽量避免。
如果某个对象封装的资源(比如文件或者线程)需要终止,此时也不要指望finalizer。
而是提供一个显示的close方法(explicit termination method),并且加入一个记录资源可用状态的私有域。
那finalizer到底有什么意义?
PS:对于本地对等体的解释,可以参考下面一段话:
另外,提到了finalizer chaining。 子类构造器会自动调用父类构造器,于是可能会想象子类finalizer自动调用父类finalizer。 如果子类复写了父类的finalizer,子类必须手动调用父类的finalier。?