說到java.io.Closeable接口就避不開java.lang.AutoCloseable接口,因為在java版本7.0時引入了java.lang.AutoCloseable接口躲庄,同時java.io.Closeable接口便繼承自java.lang.AutoCloseable接口了灰蛙。
java.io.Closeable
先說一下Closeable接口侥蒙,這個接口從java 5.0版本開始引入峰弹,其中中僅聲明了一個方法close赘理,用于關(guān)閉一個資源座韵。一直一來我都很困惑介陶,就算不實現(xiàn)這個接口堤舒,我給我的類實現(xiàn)一個close方法(或者別的方法)來完成“關(guān)閉”的功能不也是一樣的么。直到我看到下面的兩段代碼哺呜。
//第一段代碼
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異常。如果這正好發(fā)現(xiàn)在in.close被調(diào)用之時,那么這個異常就會阻止out.close被調(diào)用友驮,從而使輸出流保持在打開狀態(tài)漂羊。所以這個程序使得finally可能被意外結(jié)束。解決方式是將每一個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接口的用處耻瑟。
java.lang.AutoCloseable
在java 7.0j時引入了java.lang.AutoCloseable旨指,并且java.io.Closeable接口繼承自 java.lang.AutoCloseable。很多資源類都直接或間接的實現(xiàn)了此接口喳整。其實這個接口與try-with-resources語法是密切相關(guān)的谆构。
從AutoCloseable的注釋可知它的出現(xiàn)是為了更好的管理資源,準確說是資源的釋放框都,當一個資源類實現(xiàn)了該接口close方法搬素,在使用try-with-resources語法創(chuàng)建的資源拋出異常后,JVM會自動調(diào)用close 方法進行資源釋放魏保,當沒有拋出異常正常退出try-block時候也會調(diào)用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都實現(xiàn)了java.io.Closeable接口(間接實現(xiàn)了java.lang.AutoCloseable接口)所以上面的【第三段代碼】與【第二段代碼的】一樣“安全”。
try-with-resources
try-with-resources 是在java 7.0 版本時引入的新語法特性谓罗。使用它配合java.lang.AutoCloseable接口可以更好的對資源進行釋放粱哼,減少繁瑣的異常處理。
- 使用try-with-resources結(jié)構(gòu)無論是否拋出異常在try-block執(zhí)行完畢后都會調(diào)用資源的close方法檩咱;
- 使用try-with-resources結(jié)構(gòu)創(chuàng)建多個資源揭措,try-block執(zhí)行完畢后調(diào)用的close方法的順序與創(chuàng)建資源順序相反;
- 使用try-with-resources結(jié)構(gòu)刻蚯,try-block塊拋出異常后先執(zhí)行所有資源(try的()中聲明的)的close方法然后在執(zhí)行catch里面的代碼然后才是finally绊含;
- 只用在try的()中聲明的資源的close方法才會被調(diào)用,并且當對象銷毀的時候close不會被再次調(diào)用炊汹;
- 使用try-with-resources結(jié)構(gòu)無須顯式調(diào)用資源釋放艺挪,編程效率高,代碼更簡潔兵扬。