1. 程式人生 > >Java核心技術36講 第三講:final、finally、finalize的不同

Java核心技術36講 第三講:final、finally、finalize的不同

final、finally、finalize

  1. final可以用來修飾類、方法、變數,分別有不同的意義, final修飾的class不可以繼承擴充套件,final的變數不可以被修改,final的方法不可以重寫(override)
    final不是immutable(不可變)
    Immutable在很多場合是非常棒的選擇,然而Java預壓目前並沒有原生的不可變支援,如果要實現immutable類,我們可以做到:

    • 將class自身申明為final,這樣別人就不嗯能夠擴充套件來繞過限制了。
    • 將所有成員變數定義為private和final,並且不要實現setter方法。
    • 通常構造物件時,成員變數使用深度拷貝來初始化,而不是直接賦值,這是一種預防措施,因為你無法確定輸入物件不被其他人修改。
    • 如果確實需要實現getter方法,或者其他可能會返回內部狀態的方法,使用copy-on-write原則,建立私有的copy。
  2. 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重視執行,除非程式或者執行緒被中斷。

  1. finalize是進出類java.lang.Object的一個方法,它的設計目的是保證物件在垃圾收集前完成特定資源的回收。finalize機制現在已經不推薦使用,並且在JDK 9中開始被標記為deprecated。
    因為無法保證finalize什麼時候執行,執行的是否符合預期。使用不當會影響效能,導致程式死鎖、掛起等。
    finalize的執行時和垃圾收集關聯在一起的,一旦實現了非空的finalize方法,就會導致相應物件回收呈現數量級(40-50)上的變慢。
    finalize被設計成在物件被垃圾收集前呼叫,這就意味著實現了finalize方法的物件是個“特殊公民”,JVM要對他進行額外處理。finalize本質上成了快速回收的阻礙者,可能導致你的物件經過多個垃圾收集週期才能被回收。
    finalize拖慢垃圾收集,導致大量物件堆積,也是一種典型的導致OOM的原因。
    java.lang.ref.Cleaner可以替換原有的finalize實現,其利用了幻想引用。