在一個長時間運行的程序中,如果未能關閉一個流,則可能會泄露文件句柄,網絡端口和其他資源。因此在JDK6和更早的版本中,明智的做法實在
finally塊中關閉流。爲了得到正確的變量作用域,必須在try塊之外聲明流變量,但必須在try內完成初始化。在關閉流之前,需要檢查流變量是否爲
null。最後通常都希望忽略流關閉時出現的異常。或者最多把這些異常記錄在日誌中。例如:
/** * jdk7之前的流操作以及關閉關閉 */ public void beforeSeven(){ OutputStream os = null; try{ os = new FileOutputStream("/opt/temp/data"); //對os流的相應操作 }catch(IOException ex){ System.out.println(ex.getMessage()); }finally{ if(os!=null) try{ os.close(); }catch(IOException e){ //忽略 }
}
}
這個技術有時會稱作釋放模式,者需要在垃圾回收前釋放對象是很常見的。這個技術不僅僅適用於流,同時還適用於socket,通道,JDBC連接和語句中。
JDK7引入了“帶資源的try'” 構造(try with resource),可以更簡介的完成清理,不需要在try塊之外聲明流變量,完全可以在try塊的一個參數列表中聲明,例如:
/** * jdk7之後的流操作以及關閉 */ public void afterSereven(){ try(OutputStream os = new FileOutputStream("/opt/temp/data")){ //處理流輸出 }catch(IOException ex){ System.out.println(ex.getMessage()); } }
代碼變的如此簡介。現在不再需要finally子句。Java會對try塊參數表中聲明的所有AutoCloseable對象自動調用close()方法。
只要對象實現了closeable接口,都可以實現try with resource構造,着包括幾乎所有需要釋放的對象。到目前爲止,JavaMail Transport對象是目前唯一的例外。