1、解釋
終結器(finalizer)是不可預測的,通常是危險的,並且通常是不必要的。 它們的使用會導致不穩定的行為,性能不佳和可移植性問題。 終結器有一些有效用途,我們將在本項後面介紹,但作為一項規則,您應該避免使用它們。 從Java 9開始,終結器已被棄用,但它們仍被Java庫使用。 Java 9用清潔器(cleaner)替代終結器。
清潔器比終結器危險性小,但仍然不可預測,緩慢且通常不必要。
終結器和清除器的問題如下:
- Java 語言規範不僅不保證終結器或者清除器會被及時地執行,而且根本就不保證它們會被執行;
- 在執行終結器機制過程中,未捕獲的異常會被忽略,並且該對象的終結器機制也會終止;
- 使用終結器和清潔器機制會導致嚴重的性能問題。
- 終結方法有一個嚴重的安全問題,它們為終結方法攻擊( finalizer attack ) 打開了類的大門。
2、優點
可以避免使用終結器和清除器帶來的問題。
3、缺點
可能會喪失使用終結器和清除器的一些好處:
- 用終結器充當“安全網”
這樣做井不能保證終結器或者清除器會被及時地運行,但是遲一點釋放資源總比永遠不釋放要好(當close方法被忘記調用的時候)。
- 終止非關鍵的本地資源
在JNI中,我們可以用清除器來釋放非關鍵的本地資源。如果要釋放關鍵本地資源,仍然要調用close方法。
4、最佳實踐
在實際工作中,如果類的對象中封裝的資源(例如文件或者線程)確實需要終止,應該怎麼做才能不用編寫終結器或者清除器呢?只需讓類實現AutoCloseable接口,在使用try-catch-resources語法創建的資源拋出異常後,JVM會自動調用close方法進行資源釋放,當正常退出時try-block時候也會調用close方法。
public class AutoCloseAbleClass implements AutoCloseable {
@Override
public void close() throws Exception {
System.out.println("i am close");
}
public void dosomething() {
System.out.println("do something");
}
}
//使用try-catch-resources語法
try (AutoCloseAbleClass autoCloseable = new AutoCloseAbleClass()) {
autoCloseable.dosomething();
} catch (Exception e) {
e.printStackTrace();
}
專業從事軟件研發工作多年,在軟件設計、開發、測試、研發管理等領域裡經驗豐富,感興趣的朋友可以關注我的頭條號,相信一定會有所收穫。
如果有軟件研發方面的問題,可以諮詢我。
謝謝!
閱讀更多 IT極客老兵 的文章