2011-01-14 63 views
57

使用後的最終代替代碼爲什麼這樣做爲什麼抓

} catch (SQLException sqle) { 
    sqle.printStackTrace(); 
} finally { 
    cs.close(); 
    rs.close(); 
} 

取而代之的是

} catch (SQLException sqle) { 
    sqle.printStackTrace(); 
} 
rs.close(); 
cs.close(); 
+0

請注意,如果你的第一個'close'拋出一個異常,你永遠不會遇到第二個問題。事實證明,不要使用同樣的'try'塊使用botch'catch'和'finally'通常是個好主意。 –

+1

沒有更多的需要與java7:AutomaticResourceManagement,嘗試(new resourceDeclartion()){} –

回答

63

因爲如果一個異常得到投擲try後沒有代碼被執行除非異常被捕獲。無論try塊內發生了什麼,A finally塊總是被執行。

+5

>「除非異常被捕獲」 - 這種情況被捕獲是不是它? – code511788465541441

+0

我正在談論try/catch/finally的總體架構,而不是他的具體示例。 –

+8

這個答案是正確的,可能會拋出一個不同類型的異常。 – pilavdzice

6

因爲它確保在finally塊的東西得到執行。 catch之後的東西可能不會被執行,例如,catch塊中有另一個異常,這是非常可能的。或者你只是做你所做的事情,並拋出一個包裝原始異常的異常。

1

您的第二種方法不會執行'close'語句,因爲它已經離開了該方法。

22

看看你的catch塊 - 它會拋出DAOException。因此,即使在您提供給的樣本中,您的catch塊之後的語句也不會執行。你顯示的內容(在另一個例外中包含一個例外)是一種常見模式 - 但另一種可能性是catch塊「意外」引發異常,例如,因爲它所做的一個調用失敗。

此外,可能還有其他例外,您不會捕獲 - 要麼是因爲您聲明方法拋出它們,要麼是因爲它們是未經檢查的異常。你真的想泄漏資源,因爲IllegalArgumentException被扔到某個地方嗎?

0

這是爲了避免資源泄漏

0

finally塊中的代碼的異常是從catch塊重新拋出之前將被調用的方式。這可以確保你放入finally塊的任何清理代碼都被調用。代碼塊之外的代碼將不會運行。

2

finally關鍵字保證代碼被執行。在您的底部示例中,關閉語句不會被執行。在頂部的例子,它們被執行(你想要的!)

+0

因此,代碼神奇地停止執行catch(){}之後?我不這麼認爲。 – weiglt

8

因爲如果一個異常被拋出,

  • 代碼的最終條款將執行作爲中異常會向外傳播,即使異常會中止其餘的方法執行;

  • try/catch塊之後的代碼將不會被執行,除非異常被catch塊捕獲而不被重新拋出。

+1

+1第二點 –

0

考慮catch可以拋出一個異常,在調用堆棧中的高層函數。這將導致在將例外拋到上一級之前調用最終結果。

0

http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html這是一種誤解(並且可能起源問題):

The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList's try block can exit in one of three ways.

1. The new FileWriter statement fails and throws an IOException. 
2. The list.get(i) statement fails and throws an IndexOutOfBoundsException. 
3. Everything succeeds and the try block exits normally. 

第四屆方式(比一和IOException其他IndexOutOfBoundsException異常被拋出)丟失。前一頁中描述的代碼僅在採用finally之前獲得(1)和(2)。

我也是Java新手,在找到這篇文章之前也有同樣的問題。一般來說,潛在記憶往往更多地關注於實例而非理論。

0

finally塊可能無法始終運行,請考慮以下代碼。

public class Tester { 
    public static void main(String[] args) { 
     try { 
      System.out.println("The main method has run"); 
      System.exit(1); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      System.out.println("The finally block has run"); 
     } 
    } 
} 

在你的情況,我建議包裝裏面的代碼finally塊爲try/catch語句,因爲這顯然代碼可能會引發異常。

} catch (SQLException sqle) { 
     sqle.printStackTrace(); 
    } finally { 
    try { 
     cs.close(); 
     rs.close(); 
    } catch (Exception e) { 
     //handle new exception here 
    } 
1

如果你發現所有的錯誤,應該沒有什麼區別,否則,只有代碼中最後塊被執行,因爲代碼的執行順序是: 終於碼 - >錯誤擲 - >代碼之後捕捉 因此,一旦你的代碼拋出任何未處理的錯誤,只有最終的代碼塊按預期工作。

2

根據HeadFirst Java,即使try或catch塊具有return語句,finally塊也會運行。流程跳轉到最後,然後返回。

+0

此答案不會添加其他答案會丟失的信息。 – GhostCat

+0

我不同意。這個答案其實非常重要。到目前爲止,大多數答案都是錯誤的,但Aditi給出了一個關鍵原因,爲什麼有時候你可能想要「最後」使用,所以她值得信任。 – weiglt

相關問題