2012-10-06 44 views
4

我的catch塊中的return A代碼會發生什麼?爲什麼在最後嘗試抓住,最後的回報總是那樣?

public class TryCatchFinallyTest { 

    @Test 
    public void test_FinallyInvocation() 
    { 
     String returnString = this.returnString(); 
     assertEquals("B", returnString); 
    } 

    String returnString() 
    { 
     try 
     { 
      throw new RuntimeException(""); 
     } 
     catch (RuntimeException bogus) 
     { 
      System.out.println("A"); 
      return "A"; 
     } 
     finally 
     { 
      System.out.println("B"); 
      return "B"; 
     } 
    } 
} 
+0

很多的答案已經在這裏。以下是我可以找到的JLS中最相關的部分:http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2。這說明,如果catch塊成功完成,那麼將執行finally塊。在自己運行一個示例並閱讀該部分之後,這導致我相信在這種情況下catch塊的return語句被丟棄。 –

+0

當然,您可能會詢問JVM實現的具體細節,而不是JVM應該展現的行爲。你能澄清你在找什麼嗎? –

回答

3

最終獲得在任何返回/退出方法之前執行。因此,當你做

return "A"; 

它執行,像這樣:

System.out.println("B");//Finally block 
return "B";//Finally block 
return "A";//Return from exception catch 

,因此 「B」 返回,而不是 「A」

0

finally塊將一直執行,而catch塊只有在發生異常時纔會執行。

0

之前return "A"finally塊會被稱爲這將return "B"和您的return "A"將被跳過,永遠不會執行。因爲finally塊總是在該方法的return聲明之前執行,並且如果要從finally塊返回某些內容,則try/catchreturn聲明將始終跳過。

注意:從finally塊返回對於Java程序員來說不是一個好的做法。如果您要從finally塊返回某些內容,JAVA編譯器還會向您顯示「finally塊未正常完成」的警告。

3

也許return "A";被編譯器優化掉了,也許不是,「A」只是被動態地替換掉了。事實上,這不重要,因爲你不應該有這個代碼。

這是最後使用控制流的問題的典型例子之一:你失去了一些指令,另一個編碼器可能看不到「意圖」(實際上它只能是一個錯誤或惡作劇)。

您可能已經注意到,javac發出警告「finally塊不能正常完成」

Don't return in a finally clause

0

最後

您可以將最後從句的try-catch塊。即使從try或catch塊中引發異常,finally子句中的代碼也將始終執行。如果你的代碼在try或catch塊中有一個return語句,那麼在從該方法返回之前,finally塊中的代碼將被執行。

參考文獻http://tutorials.jenkov.com/java-exception-handling/basic-try-catch-finally.html

+0

這個引用並沒有清楚地表明,所考慮的返回語句是finally塊中的一個。 –

+0

看看最後一行,finally塊將在返回之前執行。所以當return語句發現它會調用實際返回的finally塊。 – greatmajestics

相關問題