2013-12-18 34 views
12

我念叨試穿與資源在JDK7的close()的,雖然我在想我的升級應用程序與JDK7我面臨這個問題跑..異常出山試穿與資源

例如,當使用BufferedReader時,write拋出IOException異常,close拋出IOException ..在catch塊中,我擔心拋出的IOException拋出異常,但我不會在乎關閉拋出的異常。

同樣的問題數據庫連接..和任何其他資源..

例如,我已經創建了一個自動關閉的resou RCE:

public class AutoCloseableExample implements AutoCloseable { 

    public AutoCloseableExample() throws IOException{ 
     throw new IOException(); 
    } 

    @Override 
    public void close() throws IOException { 
     throw new IOException("An Exception During Close"); 
    } 

} 

現在使用它的時候:

public class AutoCloseTest { 

    public static void main(String[] args) throws Exception { 
     try (AutoCloseableExample example = new AutoCloseableExample()) { 
      System.out.println(example); 

      throw new IOException("An Exception During Read"); 
     } catch (Exception x) { 
      System.out.println(x.getMessage()); 
     } 
    } 

} 

我怎麼能這樣的例外區分,而無需創建類的包裝,例如BufferedReader中?

大多數情況下,我把資源放在finally塊中的try/catch中,而不關心處理它。

+0

哪裏碼? –

+0

我正在談論整體概念..無論如何..我現在將添加一個代碼片段.. –

回答

10

讓我們考慮類:

public class Resource implements AutoCloseable { 

    public Resource() throws Exception { 
     throw new Exception("Exception from constructor"); 
    } 

    public void doSomething() throws Exception { 
     throw new Exception("Exception from method"); 
    } 

    @Override 
    public void close() throws Exception { 
     throw new Exception("Exception from closeable"); 
    } 
} 

和嘗試,以資源塊:

try(Resource r = new Resource()) { 
     r.doSomething(); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 

啓用全部3個throw語句。

消息「構造函數的異常」將被打印,構造函數拋出的異常將被抑制,這意味着你無法捕捉它。

2.在構造函數中的throw被移除。

現在堆棧跟蹤將打印下面的「方法的異常」和「抑制:可關閉的異常」。在這裏,你也無法捕捉到close方法拋出的被抑制的異常,但是你會對被抑制的異常非常滿意。

3.已從構造函數和方法中除去引發。

正如您可能已經猜到「可關閉的異常」將被打印。

重要提示:在所有的上述情況,你實際上是捕獲所有異常,無論他們在那裏扔。所以如果你使用try-with-resource塊,你不需要用另一個try-catch來包裝這個塊,它就是無用的。

希望它能幫助:)

+0

謝謝你的貢獻..我完全理解這個..我想到的問題是如何區分拋出的異常像doSomething()和close()方法,因爲兩者都拋出相同類型的異常。doSomething()值得捕獲,因爲流中的某些東西發生了..而從close()拋出的異常沒有那麼多在大多數情況下,重要性和讓我困惑.. –

+2

好吧,現在我明白你的意思了。如果你想從代碼中區分異常,你可以用'ex.getStackTrace()[0] .getMethodName()'來獲得異常的方法名稱。如果沒有,你可以打印堆棧跟蹤並閱讀它。 –

0

我會建議使用標誌,如下面的例子:

static String getData() throws IOException { 
    boolean isTryCompleted = false; 
    String theData = null; 
    try (MyResource br = new MyResource();) { 

     theData = br.getData(); 
     isTryCompleted = true; 

    } catch(IOException e) { 
     if (!isTryCompleted) 
      throw e; 
     // else it's a close exception and it can be ignored 
    } 

    return theData; 
} 

來源:Close resource quietly using try-with-resources