在一个长时间运行的程序中,如果未能关闭一个流,则可能会泄露文件句柄,网络端口和其他资源。因此在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对象是目前唯一的例外。