說到java.io.Closeable接口就避不開java.lang.AutoCloseable接口,由於在java版本7.0時引入了java.lang.AutoCloseable接口,同時java.io.Closeable接口便繼承自java.lang.AutoCloseable接口了。java
先說一下Closeable接口,這個接口從java 5.0版本開始引入,其中中僅聲明瞭一個方法close,用於關閉一個資源。一直一來我都很困惑,就算不實現這個接口,我給個人類實現一個close方法(或者別的方法)來完成「關閉」的功能不也是同樣的麼。直到我看到下面的兩段代碼。編程
//第一段代碼 static void copy(String src, String dest)throws IOException { InputStream in = null; OutputStream out = null; try { in = new FileInputStream(src); out = new FileOutputStream(dest); byte[] buf = new byte[1024]; int n; while ((n = in.read(buf)) >= 0) { out.write(buf, 0, n); } } finally { if (in != null) in.close(); if (out != null) out.close(); } }
上面這段代碼的問題在於,finally語句中的close方法也可能會拋出IOException異常。若是這正好發如今in.close被調用之時,那麼這個異常就會阻止out.close被調用,從而使輸出流保持在打開狀態。因此這個程序使得finally可能被意外結束。解決方式是將每個close都包裝在一個try語句塊中。從java 5.0版本開始,能夠利用Closeable接口。安全
//第二段代碼 // 對第一段代碼中的finally語句改造以下 finally { closeIgnoringIOException(in); closeIgnoringIOException(out); } private static void closeIgnoringIOException(Closeable c) { if (c != null) { try { c.close(); } catch (IOException ex) { } } }
基於以上兩段代碼我知道了java.io.Closeable接口的用處。spa
在java 7.0j時引入了java.lang.AutoCloseable,而且java.io.Closeable接口繼承自 java.lang.AutoCloseable。不少資源類都直接或間接的實現了此接口。其實這個接口與try-with-resources語法是密切相關的。code
從AutoCloseable的註釋可知它的出現是爲了更好的管理資源,準確說是資源的釋放,當一個資源類實現了該接口close方法,在使用try-with-resources語法建立的資源拋出異常後,JVM會自動調用close 方法進行資源釋放,當沒有拋出異常正常退出try-block時候也會調用close方法。對象
//第三段代碼 static void copy(String src, String dest)throws IOException { try (InputStream in=new FileInputStream(src);OutputStream out=new FileOutputStream(dest)){ byte[] buf = new byte[1024]; int n; while ((n = in.read(buf)) >= 0) { out.write(buf, 0, n); } }catch(Exception e) { System.out.println("catch block:"+e.getLocalizedMessage()); }finally{ System.out.println("finally block"); } }
由於InputStream和OutputStream都實現了java.io.Closeable接口(間接實現了java.lang.AutoCloseable接口)因此上面的【第三段代碼】與【第二段代碼的】同樣「安全」。繼承
try-with-resources 是在java 7.0 版本時引入的新語法特性。使用它配合java.lang.AutoCloseable接口能夠更好的對資源進行釋放,減小繁瑣的異常處理。token