天天看點

慎用Finalize方法以及Finalize方法的妙用

首先,要知道finalize方法跟c++的析構函數不一樣,jvm并不保證會執行。

一、慎用finalize方法

finalize方法在什麼時候被調用:

在垃圾回收的時候,某個對象要被回收的時候,會先進行一次标記,并且将該對象的finalize放到一個低優先級的線程中去執行。

等到下一次垃圾回收的時候再把這個對象回收。

jvm并不保證在垃圾回收之前能夠執行他的finalize方法,甚至在執行finalize方法的線程發生了死循環,那其他的finalize方法都無法執行了。

二、如何替代finalize方法

使用try...finally...代碼塊,将要執行的後續操作放入到finally塊中

三、finalize方法一定沒有嗎

在一些必須要做清楚的操作中,比如說InputStream,我們都知道執行完了得把流關掉

為了避免使用者的誤操作,可以在InputStream的finalize方法中關閉流,這樣為資源的釋放增加了一層保護網,雖然不保證一定能夠執行。

四、終結方法鍊?

有些時候可能遇到這樣的情況

class Super中有一個close方法需要最後執行,是以在Super類中的finalize方法中是這樣的

@Override
protected void finalize() throws Throwable(){
this.close();
}
           

但是class Sub extends Super的時候,子類把Super的finalize方法給重寫了,不再調用super.finalize(),那就完蛋了,super的finalize方法肯定不會被執行了。

怎麼解決?

方法1。

@Override
protected void finalize() throws Throwable(){
try{
//finalize subclass state
}finally{
super.finalize();
}
}
           

當然我們并不能保證來繼承super類的人能夠這樣寫,是以有個更好的方法:

使用一個finalizerGuardian:

public class Super{
//...

private final Object finalizerGuardian=new Object(){
@Override
protected void finalize() throws Throwable(){
//Super.this.close();
}
}

}
           

父類被回收的時候,内部的匿名類也一定被收回,那匿名内部類的finalize方法不管子類怎麼搞都不會受影響的。是不是很巧妙。

--Effective Java讀後感