
應幾個法國巴西和印度小程式員的邀請,
我每周在Facebook上釋出Java系列小文章,與你們也共享一下。
翻譯 | 王楷涵
這是一種在捕獲異常後更加便捷的處理資源的方式。
異常處理的公共結構如下:
The typical scenario is that the program open resources such as connections or files within the try block, and close these resources within the finally block. These code within the finally block are conventional, but if they are missed, that would bring disastrous result.
典型的情況是程式在try子產品中打開連接配接或檔案等資源,并且在finally塊中關閉這些資源。finally塊中這些代碼是正常的,但如果缺失,将帶來災難性後果。
Java是以提供了一種自動關閉這些資源的簡單方法,那就是try-with-resources。其公共結構如下:
對于上述例子,我們可以将其修改為:
以下是Oracle對try-with-resources語句的描述:
try-with-resources語句,是聲明一個或者多個資源的try語句。一個資源是一個必須在程式執行完成後被關閉的對象。try-with-resources語句確定在語句結束後每一個資源都被關閉。
任何實作了java.lang.AutoCloseable接口的對象都能被作為一個資源使用,而java.lang.AutoCloseable接口内所有的對象都實作了java.io.Closeable。
在此我們可以寫一個我們自己的自動關閉類:
運作這段程式,其輸出為:
它自動調用close()方法。
Java是如何做到這一點的,讓我們反編譯這個類:
我們能看到,編譯後生成的類和之前的一樣,沒有try-with-resources。編譯器自動增加了finally塊到程式中,這實際上是文法糖。
注意生成的代碼,編譯器使用了addSuppressed()方法向上層程式抛出一個組合異常,是以避免先前的異常被屏蔽。
最後,由于close行為的實作方式不同于resources,在使用try-with-resources語句時,應該明确所有的資源都必須重新編碼。例如以下代碼:
我們在一個語句李建立了2個流,是以編譯器隻能識别BufferedInputStream。在這種情況下,其資源結果可能會關閉失敗。一個更好的方式是分别聲明2個資源,像這樣: