finalize()是Object中的方法,当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法,让此对象处理它生前的最后事情(这个对象可以趁这个时机挣脱死亡的命运)。要明白这个问题,先看一下虚拟机是如何判断一个对象该死的。

 

判定死亡

Java采用可达性分析算法来判定一个对象是否死期已到。Java中以一系列"GC  Roots"对象作为起点,如果一个对象的引用链可以最终追溯到"GC  Roots"对象,那就天下太平。
否则如果只是A对象引用B,B对象又引用A,A,B引用链均为能达到"GC  Roots"的话,那它俩将会被虚拟机宣判符合死亡条件,具有被垃圾回收器回收的资格。
 

最后的救赎

上面提到了判断死亡的依据,但被判断死亡后,还有生还的机会。
如何自我救赎:
1.对象覆写了finalize()方法(这样在被判死后才会调用此方法,才有机会做最后的救赎);
2.在finalize()方法中重新引用到"GC  Roots"链上(如把当前对象的引用this赋值给某对象的类变量/成员变量,重新建立可达的引用).
需要注意:
finalize()只会在对象内存回收前被调用一次(The finalize method is never invoked more than once by a Java virtual machine for any given object. );
finalize()的调用具有不确定行,只保证方法会调用,但不保证方法里的任务会被执行完(比如一个对象手脚不够利索,磨磨叽叽,还在自救的过程中,被杀死回收了)。
 

finalize()的作用

虽然以上以对象救赎举例,但finalize()的作用往往被认为是用来做最后的资源回收。
基于在自我救赎中的表现来看,此方法有很大的不确定性(不保证方法中的任务执行完)而且运行代价较高。所以用来回收资源也不会有什么好的表现。
 
综上:finalize()方法并没有什么鸟用。
 
至于为什么会存在一个鸡肋的方法:书中说“它不是C/C++中的析构函数,而是Java刚诞生时为了使C/C++程序员更容易接受它所做出的一个妥协”。