總結final、finally、 finalize
阿新 • • 發佈:2018-12-10
Q1 final、finally、 finalize 有哪些不同
- final 可以用來修飾類、方法、變數,分別有不同的意義。final 修飾的 class 代表不可以繼承擴充套件,final 的變數是不可以修改的,而 final 的方法也是不可以重寫的(override)。
- finally 則是 Java 保證重點程式碼一定要被執行的一種機制。我們可以使用 try-finally 或者 try-catch-finally 來進行類似關閉 JDBC 連線、保證 unlock 鎖等動作。
- finalize 是基礎類 java.lang.Object 的一個方法,它的設計目的是保證物件在被垃圾收集前完成特定資源的回收。finalize 機制現在已經不推薦使用,並且在 JDK 9 開始被標記為 deprecated。
Q2 final最佳實踐:
- 我們可以將方法或者類宣告為 final,這樣就可以明確告知別人,這些行為是不許修改的。
- 使用 final 修飾引數或者變數,也可以清楚地避免意外賦值導致的程式設計錯誤,甚至,有人明確推薦將所有方法引數、本地變數、成員變數宣告成 final。
- final 變數產生了某種程度的不可變(immutable)的效果,所以,可以用於保護只讀資料,尤其是在併發程式設計中,因為明確地不能再賦值 final 變數,有利於減少額外的同步開銷,也可以省去一些防禦性拷貝的必要。
Q3 final需要注意的點
final 不是 immutable,對於物件和列表等需要final資料時,需要特殊處理 1. 將class自身設定為final,防止擴充套件 2. 將內部屬性定義成final或者私有化setter方法 3. 構造變數是採用深拷貝 4. getter採用copyOnWriter原則
CopyOnWrite 容器即寫時複製容器,原理就是當我們往一個容器新增元素時,不直接往當前容器新增,而是先將當前容器進行Copy,複製出新的容器,然後往新的容器進行新增元素,新增好之後,再將原來的容器引用指向新的容器。 這樣的好處就是,我們可以對CopyOnWrite容器進行併發的讀,也不需要加鎖,因為當前容器不會新增任何新的元素。 CopyOnWrite容器也是一個讀寫分離的思想
Q4 finalize的略根性
finalize常常跟GC聯絡到一起,在GC前被呼叫,若有耗時邏輯會影響GC效率,可能會導致OOM。
Q5 finalize的替代機制:
Java 平臺目前在逐步使用 java.lang.ref.Cleaner 來替換掉原有的 finalize 實現。
Cleaner 的實現利用了幻象引用(PhantomReference),這是一種常見的所謂 post-mortem 清理機制。我會在後面的專欄系統介紹 Java 的各種引用,利用幻象引用和引用佇列,我們可以保證物件被徹底銷燬前做一些類似資源回收的工作,比如關閉檔案描述符(作業系統有限的資源),它比 finalize 更加輕量、更加可靠。
public class CleaningExample implements AutoCloseable {
// A cleaner, preferably one shared within a library
private static final Cleaner cleaner = <cleaner>;
static class State implements Runnable {
State(...) {
// initialize State needed for cleaning action
}
public void run() {
// cleanup action accessing State, executed at most once
}
}
private final State;
private final Cleaner.Cleanable cleanable
public CleaningExample() {
this.state = new State(...);
this.cleanable = cleaner.register(this, state);
}
public void close() {
cleanable.clean();
}
}