2011-04-18 63 views
60

請參閱以下代碼並解釋輸出行爲。返回語句在catch中的行爲,最後

public class MyFinalTest { 

    public int doMethod(){ 
     try{ 
      throw new Exception(); 
     } 
     catch(Exception ex){ 
      return 5; 
     } 
     finally{ 
      return 10; 
     } 
    } 

    public static void main(String[] args) { 

     MyFinalTest testEx = new MyFinalTest(); 
     int rVal = testEx.doMethod(); 
     System.out.println("The return Val : "+rVal); 
    } 

} 

結果是返回瓦爾:10

Eclipse中顯示一個警告:finally block does not complete normally

catch塊中的return語句會發生什麼?

+0

的可能重複[爲什麼改變返回的變量在finally塊不會改變返回值?](http://stackoverflow.com/questions/ 16030858 /爲什麼要改變返回變量在最後塊不改變回報) – fglez 2013-04-30 07:32:21

+2

一個非常受歡迎的面試問題。 – 2014-06-29 20:09:12

回答

67

它被finally中的一個覆蓋,因爲finally在所有其他操作之後執行。

這就是爲什麼,經驗法則 - 永遠不會從finally返回。例如,Eclipse爲該片段顯示警告:「finally塊不能正常完成」

49

finally總是執行(唯一的例外是System.exit())。你可以認爲這種行爲是這樣的:

  1. ,則拋出異常
  2. 異常被捕獲和返回值被設定爲5
  3. 最後塊被執行和返回值設置爲10
  4. 的函數返回
+0

try/catch塊的一般規則:1)永不返回finally塊中的值。 2)避免在finally中拋出異常或捕捉黑色,因爲它掩蓋了原始異常。 – Matt 2012-08-08 04:36:09

+12

終於說總是執行是一件非常危險的事情。你真的不能依賴它被執行的關鍵任務操作。考慮一下像停電,jvm腐敗/崩潰等等。我知道這聽起來有點挑剔,但總是一句強烈的話,我想有時候我們會忘記我們生活在這樣的災難中的真實世界裏發生。 – corsiKa 2013-02-15 18:26:40

3

finally塊總是執行(如果執行該匹配嘗試),所以該方法返回5如在catch塊之前,它執行finally塊並返回10.

17

如果您記住虛擬機的低層佈局,這是一個簡單的問題。

  1. 返回值由catch代碼放置堆棧。
  2. 之後,執行finally代碼並覆蓋堆棧上的值。
  3. 然後,該方法返回調用者使用的最新值(10)。

如果對此類事情不確定,請回到您對底層系統的理解(最終轉到彙編程序級別)。

funny sidenote

0

的最後部分將執行始終執行。例如如果你有任何東西要釋放,或者註銷某種東西,如果發生錯誤,那麼去catch部分,最後會執行。

Session session // opened some session 
try 
{ 
// some error 
} 
catch { log.error } 
finally 
{ session.logout();} 

它不應該用來返回任何東西。你可以在外面使用。

3

enter image description here

finally塊總是得到,除非和直到System.exit()的說法是先在finally塊來執行。

所以在上面的例子中,通過try語句引發Execution並捕獲catch塊。有返回語句所以在堆棧調用值最後被添加到finally塊執行和最新的返回值被添加到堆棧頂部而返回值,堆棧返回最新值按堆棧行爲「LAST先出」所以它會返回值