1. 程式人生 > >java面試之Final、finally、finalize區別

java面試之Final、finally、finalize區別

1、final

Final可以用於成員變數(包括方法引數),方法、類。

Final成員

  •  作為變數

變數一旦被初始化便不可改變(對於基本型別,指的是值不變;對於物件型別,指的是引用不變),初始化只可能在兩個地方:定義處和建構函式。

  • 作為方法引數

對於基本型別,定義成final引數沒有什麼意義,因為基本型別就是傳值,不會影響呼叫語句中的變數;對於物件型別,在方法中如果引數確認不需要改變時,定義成final引數可以防止方法中無意的修改而影響到呼叫方法。

Final方法

  • 不可覆寫
  • 編譯器將對此方法的呼叫轉化成行內(inline)呼叫,即直接把方法主體插入到呼叫處(方法主體內容過多的時候反而會影響效率)

Final類

  • 不可繼承

2、finally

異常處理關鍵字,finally中的主體總會執行,不管異常發生是否。

2.1、當try中有return時執行順序

return語句並不是函式的最終出口,如果有finally語句,這在return之後還會執行finallyreturn的值會暫存在棧裡面,等待finally執行後再返回)

2.2、return和異常獲取語句的位置

  • 情況一(try中有return,finally中沒有return)

return num += 80”被拆分成了“num = num+80”和“return num”兩個語句,線執行try中的“num =num+80”語句,將其儲存起來,在try中的”return num“執行前,先將finally中的語句執行完,而後再將90返回。

  • 情況二(try和finally中均有return)

try中的return被”覆蓋“掉了,不再執行。

  • 情況三(finally中改變返回值num)

雖然在finally中改變了返回值num,但因為finally中沒有return該num的值,因此在執行完finally中的語句後,test()函式會得到try中返回的num的值,而try中的num的值依然是程式進入finally程式碼塊前保留下來的值,因此得到的返回值為10。並且函式最後面的return語句不會執行。

  • 另外一種情況:將num的值包裝在Num類中

6.2.3、簡單地總結如下:

try語句在返回前,將其他所有的操作執行完,保留好要返回的值,而後轉入執行finally中的語句,而後分為以下三種情況:

情況一:如果finally中有return語句,則會將try中的return語句”覆蓋“掉,直接執行finally中的return語句,得到返回值,這樣便無法得到try之前保留好的返回值。

情況二:如果finally中沒有return語句,也沒有改變要返回值,則執行完finally中的語句後,會接著執行try中的return語句,返回之前保留的值。

情況三:如果finally中沒有return語句,但是改變了要返回的值,這裡有點類似與引用傳遞和值傳遞的區別,分以下兩種情況,:

  • 如果return的資料是基本資料型別,則在finally中對該基本資料的改變不起作用,try中的return語句依然會返回進入finally塊之前保留的值。
  • 如果return的資料是引用資料型別,而在finally中對該引用資料型別的屬性值的改變起作用,try中的return語句返回的就是在finally中改變後的該屬性的值。

6.3、finalize

類的Finalize方法,可以告訴垃圾回收器應該執行的操作,該方法從Object類繼承而來。在從堆中永久刪除物件之前,垃圾回收器呼叫該物件的Finalize方法。注意,無法確切地保證垃圾回收器何時呼叫該方法,也無法保證呼叫不同物件的方法的順序。即使一個物件包含另一個物件的引用,或者在釋放一個物件很久以前就釋放了另一個物件,也可能會以任意的順序呼叫這兩個物件的Finalize方法。如果必須保證採用特定的順序,則必須提供自己的特有清理方法。