final、finally和finalize的區別
網上已經很多這個話題了,都很不錯,目前準備面試校招,複習一遍java基礎,故作此.
1.final是一個java關鍵字
1) final修飾的類,不能被繼承,所以抽象類,不能使用final修飾(沒有意義,編譯報錯),另外要注意final類中的所有成員方法都會被隱式地指定為final方法.(自己寫很少用來修飾類,java中典型的是String)
2) final修飾的方法不能被重寫,需要注意的是:類的private方法會隱式地被指定為final方法.
3) final修飾的變數.分為兩種情況.(通常大點專案使用,把所有的常量放在一個常量類中)
i>引用型變數(物件),則表示該物件對其初始化之後便不能再讓其指向另一個物件(可以set內部屬性,但不能重新指向)
ii>基本資料型別的變數(可以說是常量了),則其數值一旦在初始化之後便不能更改.需要注意的是:
當用final作用於類的成員變數時,成員變數(注意是類的成員變數,區域性變數只需要保證在使用之前被初始化賦值即可)必須在定義時或者構造器中進行初始化賦值,而且final變數一旦被初始化賦值之後,就不能再被賦值了。
另外,成員變數是即類變數,是分配在java記憶體的堆裡面的,而區域性變數是在棧中的,這也是造成上面區別的原因吧.
2.finally是在異常處理時提供finally塊來執行最終操作
在try(){}catch(){}中無論發生異常,或者return,finally都會執行,一般用於關閉資源.
需要注意的是return操作,當然我們一般try()catch()中不會這麼玩,不過面試題還是偶爾有的,需要記一下
1.try{ int x = 1; return x; } finally{ x++;} 很簡單的例子,如果try中返回變數x,finally處理中,又對x++,最後返回的是x=1;
執行順序是,try中return x,這時儲存的當前x值,然後執行finally操作,這時finally對x操作,完成後,執行try中的return 這是返回的是try儲存的x值,既1;
2.try{ int x = 1; return x; } finally{ x++;return x;} 如果try中返回變數x,finally處理,又對x++,再次返回x,最後返回的是x=2;
前面和1一樣,但finally return 時.覆蓋掉了try中的return,誰叫finally是老大啊.....
3.try{ int x = 1; throw 異常 } catch {x++;return x;} finally{ x++;return x;} 如果try中丟擲異常,catch 處理x加一,並返回x,finally處理,又對x++,再次返回x,最後返回的是x=3;
和2一樣,稍微要注意的是,執行順序是try(){} > catch(){} >finally{},畢竟程式碼也是順序- -.
總結: try(){}catch(){}中無論何處return,finally一樣會返回,try中return,這時儲存的當前return值,然後執行finally操作,這時finally完成操作,完成後,執行try中的return 這時返回的是try{}儲存的return值(無論finally是否修改);如果finally也進行了return操作,則會覆蓋try{}中的return;
3.finalize()是Object的一個protected方法
1.finalize()是Object的protected方法,子類可以覆蓋該方法以實現資源清理工作,GC在回收物件之前呼叫該方法。
2.finalize()與C++中的解構函式不是對應的。C++中的解構函式呼叫的時機是確定的(物件離開作用域或delete掉),但Java中的finalize的呼叫具有不確定性(坑爹的方法) ,該方法好像是Java早期對C++程式設計師的屈服產物(好像在哪看過),現已基本不用,以前常用於關閉資源,現在我們用finally,更可靠方便.
3.finalize方法可能會帶來效能問題,因為JVM通常在單獨的低優先順序執行緒中完成finalize的執行
4.物件再生問題:finalize方法中,可將待回收物件賦值給GC Roots可達的物件引用,從而達到物件再生的目的
大概過程:首先,大致描述一下finalize流程:當物件變成(GC Roots)不可達時,GC會判斷該物件是否覆蓋了finalize方法,若未覆蓋,則直接將其回收。否則,若物件未執行過finalize方法,將其放入F-Queue佇列,由一低優先順序執行緒執行該佇列中物件的finalize方法。執行finalize方法完畢後,GC會再次判斷該物件是否可達,若不可達,則進行回收,否則,物件“復活”。
注意:finalize方法至多由GC執行一次.第二次又被當垃圾回收時,就不會管你,是否重寫了finalize().