避免使用終結

      終結方法(finalizer)通常是不可預測的,也是很危險的,一般情況下是不必要的。
   如果程序依賴於終結方法被執行的時間點,那麼這個程序的行爲在不同的JVM實現中會大相徑庭。Java語言規範不僅不保證終結方法會被及時的執行,而且根本不保證他們會被執行。不應該依賴終結方法來更新重要的持久狀態。

   不要被System.gc和System.runFinalization這兩個方法所誘惑,他們確實增加了終結方法被執行的機會,但是他們不保證終結方法一定被執行。唯一聲稱保證終結方法被執行的方法是System.runFinalizersOnExit,以及他臭名昭著的孿生兄弟Runtime.runFinalizersOnExit。這兩個方法都有致命的缺陷,都被廢棄了。使用終結方法有一個非常嚴重的(Severe)性能損失。提供一個顯示終止的方法來終止一些必要的資源。

   顯示終止方法的典型例子是InputStream、OutputStream和java.sql.Connection上的close方法。
   另一個例子是java.util.Timer上的cancel方法,它執行必要的狀態改變,使得與Timer實例相關聯的該線程溫和的終止自己。
   java.awt中的例子還包括Graphics.dispose和Window.dispose。
   Image.flush,他會釋放所有與Image實例相關聯的資源,但是該實例仍然處於可用的狀態,如果有必要的話,會重新分配資源。

總結:

  除非作爲安全網,或者是爲了終止非關鍵的本地資源,否則請不要使用終結方法。在這些很少見的情況下,既然使用了終結方法,就要記住調用super.finalize。如果用終結方法作爲安全網,要記得記錄終結方法的非法用法。最後,如果需要吧終結方法與公有的非final類關聯起來,請考慮使用終結方法守護者,以確保即使子類的終結方法未能調用super.finalize,該終結方法也會被執行。

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

demo:

class A {    
	    B b;    
	    
	    public A(B b) {    
	        this.b = b;    
	    }    
	    
	    @Override    
	    public void finalize() {    
	        System.out.println("A finalize");    
	        C.a = this;    
	    }    
	}   
	  
	class B {    
	    String name;    
	    int age;    
	    
	    public B(String name, int age) {    
	        this.name = name;    
	        this.age = age;    
	    }    
	    
	    @Override    
	    public void finalize() {    
	        System.out.println("B finalize");    
	    }    
	    
	    @Override    
	    public String toString() {    
	        return name + " is " + age;    
	    }    
	}    
	  
	  
	class C {    
	    static A a;    
	}   
	  
	public class Main {    
	    public static void main(String[] args) throws Exception {    
	        A a = new A(new B("allen", 20));    
	        a = null;    
	    
	        System.gc();    
	        Thread.sleep(5000);    
	        System.out.println(C.a.b);    
	    }    
	} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章