1. 程式人生 > >final、finally和finalize的區別

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().

         希望與諸君共同學習進步!堅持,努力.共勉