Try-with-resources (TWR)
在處理IO的代碼中,我們會使用大量的try...catch()...finally...語法,其中會在finally進行IO的close操作,寫過python的都知道,這種操作可以使用try-with-resources操作,幸運的是Java7也有了此特性,比如之前的語法:
private void test(URL url, File file) { InputStream is = null; try { is = url.openStream(); OutputStream out = new FileOutputStream(file); try { byte[] buf = new byte[4096]; int len; while ((len = is.read(buf)) >= 0) out.write(buf, 0, len); } catch (IOException iox) { } finally { try { out.close(); } catch (IOException closeOutx) { } } } catch (FileNotFoundException fnfx) { } catch (IOException openx) { } finally { try { if (is != null) is.close(); } catch (IOException closeInx) { } } }
而使用try-with-resources語法,則可以簡化為:
try (OutputStream out = new FileOutputStream(file); InputStream is = url.openStream()) { byte[] buf = new byte[4096]; int len; while ((len = is.read(buf)) > 0) { out.write(buf, 0, len); } }
但是使用try-with-resources的時候還是由可能造成資源沒有關閉,比如在try()中有錯誤時,比如:
try ( ObjectInputStream in = new ObjectInputStream(new FileInputStream("someFile.bin")) ) { ... }
比如文件存在,但卻不是寫入的對象序列,因此會造成不正常打開,此時ObjectInputStream不能正確初始化,且不會關閉,因此正確的方式是分開資源變量:
try ( FileInputStream fin = new FileInputStream("someFile.bin"); ObjectInputStream in = new ObjectInputStream(fin) ) { ... }
TWR特性是使用了java7的新的接口AutoCloseable,可以使用try-with-resources語法的資源必須實現該接口。而Closeable繼承了AutoCloseable,因此我們常用的資源類都可以使用。