Effective Java之避免使用终结方法(七)
1.終結(jié)方法的缺點
1.終結(jié)方法不能保證及時執(zhí)行,因此注重時間的任務不應該由終結(jié)方法來完成。例如:用終結(jié)方法去關(guān)閉已經(jīng)打開的文件,這是一種嚴重錯誤,因為打開文件描述符是一種很有限的資源,如果jvm延遲終結(jié)方法,導致多個文件處于打開的狀態(tài)。
2.終結(jié)方法不能保證一定會被執(zhí)行。如果企圖通過終結(jié)方法釋放共享資源上的永久鎖,會使整個分布式系統(tǒng)掛掉。
3.不要被System.gc和System.runFinalization所迷惑,它們確實增加了終結(jié)方法執(zhí)行的機會,但是它們并不保證終結(jié)方法一定執(zhí)行。
4.使用終結(jié)方法會有嚴重的性能損失
2.終結(jié)方法的替代品-顯式終止方法
1.顯式的終止方法,要求該類的客戶端在每個實例不再使用時調(diào)用這個方法。如inputstream的close方法。
2.顯示的終止方法必須在一個私有域中記錄“該對象不再有效”,然后如果這個類的方法在對象終止之后被調(diào)用了,那么這個方法會先檢查這個域,并拋出IllegalStateException錯誤。
3.顯式的終止方法通常與try-catch結(jié)構(gòu)結(jié)合起來使用,來確認即使終止。
3.終結(jié)方法用途
充當安全網(wǎng),如果對象忘記調(diào)用顯示終止方法時,終結(jié)方法發(fā)現(xiàn)資源還沒有終止,則應該在日志中記錄一條警告。
本地對等體(native peer),一個本地對象(native object),普通對象通過本地方法(native method)委托給一個本地對象。
因為本地對等體不是一個普通對象,所以垃圾回收器不會知道它,當它的java對等體被回收的時候,它不會被回收,這時候就要用到終止方法,如果本地對等體不含有關(guān)鍵資源,那么終結(jié)方法便是最恰當?shù)姆椒?#xff0c;如果含有關(guān)鍵資源,那么該類應該具有一個顯式終止方法。
4.終結(jié)方法鏈問題:
如果類(不是Object)有終結(jié)方法,并且子類覆蓋了終結(jié)方法,子類的終結(jié)方法就必須手工調(diào)用超類的終結(jié)方法,否則超類的終結(jié)方法將永遠也不會被調(diào)用。
為了避免這個問題的發(fā)生,我們使用終結(jié)方法守衛(wèi)者方法:
public class FinalizerGuardian { private final Object finalizerGuardian = new Object() { protected void finalize() throws Throwable { System.out.println("finalize " + this); }; }; public void doSomething() { System.out.println("do something"); } public static void main(String[] args) { FinalizerGuardian fg = new FinalizerGuardian(); fg.doSomething(); fg = null; // 使用十次顯式gc增加調(diào)用終結(jié)方法的概率 for (int i = 0; i < 10; i++) { System.gc(); } } }這種方式把終結(jié)方法放在一個匿名的內(nèi)部類中,這個匿名內(nèi)部類的作用是終結(jié)它的外圍實例,這種匿名類的單個實例叫做終結(jié)方法守衛(wèi)者,當終結(jié)方法守衛(wèi)者被終結(jié)的時候,他會調(diào)用它的終結(jié)方法讓外圍實例終結(jié),這樣看起來就像外圍實例自己執(zhí)行終結(jié)方法一樣。
總結(jié)
以上是生活随笔為你收集整理的Effective Java之避免使用终结方法(七)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Effective Java之覆盖equ
- 下一篇: Effectice Java之始终覆盖t