2016-04-25 235 views
0

按照Oracle文檔試用資源是否可能無法關閉資源?

try-with-resources語句是聲明一個或多個資源的try語句。資源是一個對象,在程序結束後必須關閉。 try-with-resources語句確保每個資源在語句結束時都關閉。實現java.lang.AutoCloseable的任何對象,包括實現java.io.Closeable所有對象,可以用來作爲資源

如果資源沒有實現AutoCloseable不能try塊內聲明的,必須在正文部分&中聲明必須在finally塊中明確關閉。 是否有可能嘗試與資源無法清理資源,除非像使用嵌套資源那樣錯誤地使用習語& close()調用對於底層資源不是冪等的嗎? 我的理解是try-with-resource只能確保close()在場景後面被調用,但如果關閉本身並沒有關閉底層資源,那麼嘗試使用資源對於清理資源仍然不起作用。 有沒有人有相反的觀點或更多的澄清?

+1

您是否可以爲您認爲可能出現故障的情況生成代碼? – djechlin

+0

這可能歸結爲「什麼時候終止塊不能運行」(這是非常罕見的,基本上只是像System.exit那樣它應該無關緊要的情況)? – Thilo

+2

另請注意,所有試用資源都是調用'close'方法。如果該方法正確地完成其工作是另一個問題。 – Thilo

回答

1

無視實際上不起作用的代碼(就像您的close()方法沒有真正關閉資源的示例),或者是將調試器附加到邊清理的完全外部因素,我可以想到三種情況:try-with - 資源可能無法清除資源:

  • 電源故障,硬件故障,操作系統崩潰或虛擬機崩潰。對於這樣的事情,軟件可以做的不多,所以它們超出了資源處理的範圍。但是,如果您想要管理諸如強制鎖定文件之類的事情,以及嘗試使用資源語句時,仍需記住這一點。
  • 異步例外,例如由Thread.stop()生成的例外。如果一個線程在清理代碼時以這種方式「停止」,那麼清理代碼將被中止。這種異步例外的不安全性是爲什麼Thread.stop()deprecated並且替換爲Thread.interrupt(),這是安全的。
  • 如果調用System.exit()。這可能被認爲是上述任何一種情況,只不過它可能發生在「正常情況下」。

在所有其他方面,您應該能夠放心,close()將被稱爲。 Try-with-several-resources與嵌套try塊相同,因此清理代碼拋出異常不會停止其他清理例程。