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