2016-10-26 75 views
2

我正在使用try表達式,並閱讀了關於此的java文檔。 https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
當使用try資源打開資源時會發生什麼情況會引發異常?

我明白,如果資源關閉和try塊中的代碼都拋出異常,那麼關閉的異常被抑制。但是,在資源開放的情況下會發生什麼情況會引發異常?我是否需要使用封閉式捕獲來捕獲它?這是如何表現的?

try (Statement stmt = con.createStatement()) { 
     // use stmt here 
} 

可以說創建語句拋出一個錯誤,現在會發生什麼?它被壓制了嗎?我想區分此異常和語句創建成功時可能拋出的任何異常,並且該塊會拋出異常。

感謝您的幫助!

回答

1

可以說創建語句拋出一個錯誤,現在會發生什麼? 被壓制了嗎?

不,它沒有被抑制,它被拋出,因爲它確實是根據Java規範§14.20.3.1你的代碼就相當於:

Throwable primaryExc = null; 
Statement stmt = null; 
try { 
    stmt = con.createStatement(); 
    // use stmt here 
} catch (Throwable e) { 
    primaryExc = e; 
    throw e; 
} finally { 
    if (stmt != null) { 
     if (primaryExc != null) { 
      try { 
       stmt.close(); 
      } catch (Throwable ex) { 
       primaryExc.addSuppressed(ex); 
      } 
     } else { 
      stmt.close(); 
     } 
    } 
} 

所以你可以看到,如果createStatement()拋出一個例外,如果沒有明確捕獲,調用代碼將不得不將這個異常作爲正常異常處理。

請注意,如果stmt.close()在被try-with-resources語句自動調用時拋出異常,則調用代碼將不得不處理此異常,因爲它也不會被抑制。

抑制異常的能力已被添加爲try-with-resources聲明能夠得到同時呼籲資源close()異常時已經在try塊拋出已拋出的異常,例如:

try (Statement stmt = con.createStatement()) { 
    throw new RuntimeException("foo"); 
} catch (Exception e) { 
    // Here e is my RuntimeException, if stmt.close() failed 
    // I can get the related exception from e.getSuppressed() 
} 
相關問題