finalize()
方法不像C++
中的析構,C++
中必須使用析構來釋放內存和資源。在Java
中,內存通常由GC(垃圾回收器)回收,資源常採用try...finally
來完成。
使用finalize方法缺點
不能保證被執行
1). 程序被強制終結,不會調用
finalize
方法
2).finalize
方法執行時拋出異常,不會繼續執行不能保證及時被執行
1). 對時間敏感的任務不能在
finalize
中執行,譬如文件資源回收性能損失
- 移植性差
1). 不同JVM
實現的GC
不同,導致finalize
在不同平臺不一定都能運行
合理用途
安全網-最後釋放內存和資源保障
當對象使用者忘記採用try...finaly
顯示釋放資源,則finalize
方法可作爲最後的保障(可能釋放總比不會釋放要好)。譬如FileInputStram
、FileOutputStram
、Timer
、Connection
等中的finalize
方法。回收本地對等體
本地對等體:指
Java
通過JNI
調用本地方法,將普通對象委託給本地對象的對象。本地對等體不能被JVM GC
回收。當本地對等體沒有關鍵資源時可通過
GC
回收,否則最好顯示終結。
在使用finalize
方法時,需要注意的是如果子類重寫了父類的finalize
方法,則子類並不會默認調用父類的finalize
方法。你需要顯示的調用,如下所示:
@Override
public void finalize() throws Throwable {
try {
//子類的finalize實現
} finally {
//調用父類的finalize方法
super.finalize();
}
}
你也可以採用終結方法守衛者,代碼如下:
public class Parent {
private Object finalizeGuardian = new Object() {
@Override
protected void finalize() throws Throwable {
System.out.println("Parent Guardian finalize");
}
};
private static void testFinalize() {
Sub sub = new Sub();
sub = null;
System.gc();
}
//輸出結果爲:
//Sub finalize
//Parent Guardian finalize
public static void main(String[] args) {
testFinalize();
}
}
class Sub extends Parent {
@Override
protected void finalize() throws Throwable {
System.out.println("Sub finalize");
}
}
總結
- 強烈不推薦使用finalize方法;
- 萬一必須要使用,注意子類必須顯示調用父類
finalize
方法,或採用終結方法守衛者方法