Effective Java 學習筆記之第七條——避免使用終結(finalizer)方法,effectivefinalizer

來源:互聯網
上載者:User

Effective Java 學習筆記之第七條——避免使用終結(finalizer)方法,effectivefinalizer

 

避免使用終結方法(finalizer)

終結方法(finalizer)通常是不可預測的,也是很危險的,一般情況下是不必要的。

不要把finalizer當成C++中解構函式的對應物。java中,當對象不可達時(即沒有引用指向這個對象時),會由記憶體回收行程來回收與該對象相關聯的記憶體資源;而其他的記憶體資源,則一般由try-finally代碼塊來完成類似的工作。

一、finalizer的缺點:

1. 終結方法的缺點在於不能保證會被及時地執行。

及時執行finalizer方法是JVM記憶體回收方法的一個主要功能。由於不同JVM的記憶體回收演算法不同,JVM會“非故意的”順延強制終結方法,因此終結方法的執行時間點是非常不穩定的。

2.finalizer方法的線程優先順序比當前程式的其他線程優先順序要低,且JAVA語言規範不保證哪個線程可以執行finalizer方法。

3.JAVA語言規範不僅不保證及時執行finalizer方法,還不保證一定會執行finalizer方法。當程式終止時,有可能一些對象的finalizer方法還沒有執行。——不應該依賴finalizer方法來更新重要的持久狀態。

4.System.gc和System.runFinalization不保證finalizer一定執行。

5.System.runFinalizersOnExit Runtime.runFinalizersOnExit 可以保證finalizer一定執行,但是這兩個方法已經廢棄。

6.如果未捕獲的異常在finalizer方法中拋出來,這個異常可以被忽略(警告都不會列印出來),且finalizer方法會終止。這樣這個異常就使對象處於“被破壞”的狀態,如果另一個線程要使用這個對象,就可能發生不確定的行為。

7.finalizer方法會有非常嚴重的(Severe)效能損失

 

二、不用finalizer方法,怎麼來實現線程中對象資源的終止呢?

使用顯示終止方法。

顯示終止方法的要求:

1.執行個體必須記錄下自己是否已經被終止了

2.顯示終止方法必須在一個私人域中記錄下“該對象已經不再有效”

3.在執行終止方法之後,執行對象其他方法時要檢查“該對象已經不再有效”私人域,拋出IllegalStateException。

顯示終止方法的例子:

1.InputStream

2.OutputStream

3.java.sql.Connection

4.java.util.Timer

顯示終止方法的使用方法:通常和try-finally一起使用,以確保及時終止。

FileInputStream fileInputStream = new FileInputStream();

try{

    //Do something about fileInputStream;

}finally{

    fileInputStream.close();

}

 

三、終結方法的合法用途。

1.作為安全網——顯示終止方法忘記調用的時候

2.終止非關鍵的本地資源(android JNI操作中)

 

四、終結方法的執行過程中要保證:如果子類的終結過程出現異常,超類的終結過程也會得到執行。

由於終結方法鏈不會自動執行,因此我們需要手動保證這一點。

方法一:使用try – finalize 代碼結構

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

方法二:使用finalizer guardian(終結方法守衛者)

class A {

    //終結守衛者
    private final Object finalizerGuardian = new Object() {

        @Override
        //終結守衛者的終結方法將被執行
        protected void finalize() {

            //finalizer這outer class ——A
            System.out.println("A finalize by the finalizerGuardian");
        }
    };

 

總之,

1.除非是作為安全網或者是為了終結非關鍵的本地資源,否則請不要使用終結方法。

2.如果確實需要,可以使用顯示終止方法

2.如果沒辦法真的使用了finalize,別忘記了調用super.finalize()。還可以考慮是否使用終結方法守衛者,使未調用super.finalize()方法的類的父類的終結方法也會被執行。

 

參考資料:

《Effective Java 第二版》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.