java.io.Closeable接口

說(shuō)到j(luò)ava.io.Closeable接口就避不開java.lang.AutoCloseable接口,因?yàn)樵趈ava版本7.0時(shí)引入了java.lang.AutoCloseable接口,同時(shí)java.io.Closeable接口便繼承自java.lang.AutoCloseable接口了。

java.io.Closeable

先說(shuō)一下Closeable接口,這個(gè)接口從java 5.0版本開始引入,其中中僅聲明了一個(gè)方法close,用于關(guān)閉一個(gè)資源。一直一來(lái)我都很困惑,就算不實(shí)現(xiàn)這個(gè)接口,我給我的類實(shí)現(xiàn)一個(gè)close方法(或者別的方法)來(lái)完成“關(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();
  }
}

上面這段代碼的問(wèn)題在于,finally語(yǔ)句中的close方法也可能會(huì)拋出IOException異常。如果這正好發(fā)現(xiàn)在in.close被調(diào)用之時(shí),那么這個(gè)異常就會(huì)阻止out.close被調(diào)用,從而使輸出流保持在打開狀態(tài)。所以這個(gè)程序使得finally可能被意外結(jié)束。解決方式是將每一個(gè)close都包裝在一個(gè)try語(yǔ)句塊中。從java 5.0版本開始,可以利用Closeable接口。

//第二段代碼
// 對(duì)第一段代碼中的finally語(yǔ)句改造如下
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時(shí)引入了java.lang.AutoCloseable,并且java.io.Closeable接口繼承自 java.lang.AutoCloseable。很多資源類都直接或間接的實(shí)現(xiàn)了此接口。其實(shí)這個(gè)接口與try-with-resources語(yǔ)法是密切相關(guān)的。

從AutoCloseable的注釋可知它的出現(xiàn)是為了更好的管理資源,準(zhǔn)確說(shuō)是資源的釋放,當(dāng)一個(gè)資源類實(shí)現(xiàn)了該接口close方法,在使用try-with-resources語(yǔ)法創(chuàng)建的資源拋出異常后,JVM會(huì)自動(dòng)調(diào)用close 方法進(jìn)行資源釋放,當(dāng)沒(méi)有拋出異常正常退出try-block時(shí)候也會(huì)調(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");
  }
}

因?yàn)镮nputStream和OutputStream都實(shí)現(xiàn)了java.io.Closeable接口(間接實(shí)現(xiàn)了java.lang.AutoCloseable接口)所以上面的【第三段代碼】與【第二段代碼的】一樣“安全”。

try-with-resources

try-with-resources 是在java 7.0 版本時(shí)引入的新語(yǔ)法特性。使用它配合java.lang.AutoCloseable接口可以更好的對(duì)資源進(jìn)行釋放,減少繁瑣的異常處理。

  1. 使用try-with-resources結(jié)構(gòu)無(wú)論是否拋出異常在try-block執(zhí)行完畢后都會(huì)調(diào)用資源的close方法;
  2. 使用try-with-resources結(jié)構(gòu)創(chuàng)建多個(gè)資源,try-block執(zhí)行完畢后調(diào)用的close方法的順序與創(chuàng)建資源順序相反;
  3. 使用try-with-resources結(jié)構(gòu),try-block塊拋出異常后先執(zhí)行所有資源(try的()中聲明的)的close方法然后在執(zhí)行catch里面的代碼然后才是finally;
  4. 只用在try的()中聲明的資源的close方法才會(huì)被調(diào)用,并且當(dāng)對(duì)象銷毀的時(shí)候close不會(huì)被再次調(diào)用;
  5. 使用try-with-resources結(jié)構(gòu)無(wú)須顯式調(diào)用資源釋放,編程效率高,代碼更簡(jiǎn)潔。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,890評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,760評(píng)論 18 399
  • /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home...
    光劍書架上的書閱讀 3,928評(píng)論 2 8
  • 自然給了鄉(xiāng)村以落后, 也給了她涼風(fēng)。 自然給了城市以熱鬧, 也給了她空調(diào)。
    愛(ài)花的小巫閱讀 351評(píng)論 0 0
  • 八點(diǎn)半了勉強(qiáng)爬起來(lái)準(zhǔn)備站樁,心想可別打擾我?。傉竞么蜷_音樂(lè),就來(lái)了一通賣房的騷擾電話。繼續(xù)聽著引導(dǎo)語(yǔ)做準(zhǔn)備工作,...
    閔靜閱讀 249評(píng)論 0 1