Java核心技術36講 第三講:final、finally、finalize的不同
阿新 • • 發佈:2019-02-02
final、finally、finalize
-
final可以用來修飾類、方法、變數,分別有不同的意義, final修飾的class不可以繼承擴充套件,final的變數不可以被修改,final的方法不可以重寫(override)
final不是immutable(不可變)
Immutable在很多場合是非常棒的選擇,然而Java預壓目前並沒有原生的不可變支援,如果要實現immutable類,我們可以做到:- 將class自身申明為final,這樣別人就不嗯能夠擴充套件來繞過限制了。
- 將所有成員變數定義為private和final,並且不要實現setter方法。
- 通常構造物件時,成員變數使用深度拷貝來初始化,而不是直接賦值,這是一種預防措施,因為你無法確定輸入物件不被其他人修改。
- 如果確實需要實現getter方法,或者其他可能會返回內部狀態的方法,使用copy-on-write原則,建立私有的copy。
-
finally是Java保證重點程式碼一定要被執行的一種機制。我們可以使用try-finally或者try-catch-finally來進行類似關閉JDBC連線、保證unlock所等動作。
列幾個finally不會被執行的情況:
- try-catch異常退出。
try{
System.exit(1);
}finally{
print("hello");
}
- 無限迴圈:
try{ while(true){ print("hi"); } }finally{ print("hello"); }
- 執行緒被殺死:
當執行try,finally的縣城北殺死時,finally也無法執行。
不要在finally中使用return語句。finally重視執行,除非程式或者執行緒被中斷。
- finalize是進出類java.lang.Object的一個方法,它的設計目的是保證物件在垃圾收集前完成特定資源的回收。finalize機制現在已經不推薦使用,並且在JDK 9中開始被標記為deprecated。
因為無法保證finalize什麼時候執行,執行的是否符合預期。使用不當會影響效能,導致程式死鎖、掛起等。
finalize的執行時和垃圾收集關聯在一起的,一旦實現了非空的finalize方法,就會導致相應物件回收呈現數量級(40-50)上的變慢。
finalize被設計成在物件被垃圾收集前呼叫,這就意味著實現了finalize方法的物件是個“特殊公民”,JVM要對他進行額外處理。finalize本質上成了快速回收的阻礙者,可能導致你的物件經過多個垃圾收集週期才能被回收。
finalize拖慢垃圾收集,導致大量物件堆積,也是一種典型的導致OOM的原因。
java.lang.ref.Cleaner可以替換原有的finalize實現,其利用了幻想引用。