说到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,用于关闭一个资源。一直一来我都很困惑,就算不实现这个接口,我给我的类实现一个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接口的用处。

java.lang.AutoCloseable

在java 7.0j时引入了java.lang.AutoCloseable,并且java.io.Closeable接口继承自 java.lang.AutoCloseable。很多资源类都直接或间接的实现了此接口。其实这个接口与try-with-resources语法是密切相关的。

从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

try-with-resources 是在java 7.0 版本时引入的新语法特性。使用它配合java.lang.AutoCloseable接口可以更好的对资源进行释放,减少繁琐的异常处理。

  1. 使用try-with-resources结构无论是否抛出异常在try-block执行完毕后都会调用资源的close方法;
  2. 使用try-with-resources结构创建多个资源,try-block执行完毕后调用的close方法的顺序与创建资源顺序相反;
  3. 使用try-with-resources结构,try-block块抛出异常后先执行所有资源(try的()中声明的)的close方法然后在执行catch里面的代码然后才是finally;
  4. 只用在try的()中声明的资源的close方法才会被调用,并且当对象销毁的时候close不会被再次调用;
  5. 使用try-with-resources结构无须显式调用资源释放,编程效率高,代码更简洁。

【转】java.io.Closeable接口的更多相关文章

  1. java.io.Closeable 接口

    package java.io; import java.io.IOException; /** * 关闭数据资源*/public interface Closeable extends AutoCl ...

  2. java.io.Flushable 接口

    package java.io; import java.io.IOException; /** * 在什么情况下用呢? 缓冲输出到一个流中的情况下,这个流要刷新. */ public interfa ...

  3. JDK1.8 java.io.Serializable接口详解

    java.io.Serializable接口是一个标志性接口,在接口内部没有定义任何属性与方法.只是用于标识此接口的实现类可以被序列化与反序列化.但是它的奥秘并非像它表现的这样简单.现在从以下几个问题 ...

  4. JDK源码阅读(五)java.io.Serializable接口

    package java.io; public interface Serializable { } (1)实现Serializable接口的类,将会被提示提供一个 serialVersionUID ...

  5. java.io.DataInput接口和java.io.DataOutput接口详解

    public interface DataInput DataInput 接口用于从二进制流中读取字节,并重构所有 Java 基本类型数据.同时还提供根据 UTF-8 修改版格式的数据重构 Strin ...

  6. Java IO 四大附加接口、try-with-resource

    Java IO 四大附加接口.try-with-resource @author ixenos 四大附加接口 Closeable.Flushable.Readable.Appendable Close ...

  7. Java IO 之 OutputStream源码

    Writer      :BYSocket(泥沙砖瓦浆木匠) 微         博:BYSocket 豆         瓣:BYSocket FaceBook:BYSocket Twitter   ...

  8. JAVA(三)JAVA常用类库/JAVA IO

    成鹏致远 | lcw.cnblog.com |2014-02-01 JAVA常用类库 1.StringBuffer StringBuffer是使用缓冲区的,本身也是操作字符串的,但是与String类不 ...

  9. Java -- IO -- 目录

    操作文件的类 -- -- File File类的基本介绍 使用File类操作文件 范例 -- -- 列出指定目录的全部内容 RandomAccessFile类 使用RandomAccessFile类写 ...

随机推荐

  1. LODOP和C-LODOP注册与角色等简短问答【增强版】

    之前的简短问答:Lodop.c-lodop注册与角色简短问答.Lodop简短问答客户反馈篇 及排查步骤 及注册相关本文重新整理相关简短问答,调整问答顺序,增加相关的问答. 其他相关(非简短问答):LO ...

  2. [LeetCode] 348. Design Tic-Tac-Toe 设计井字棋游戏

    Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...

  3. .Net Core 定时任务TimeJob

    转载自:https://blog.csdn.net/u013711462/article/details/53449799 定时任务 Pomelo.AspNetCore.TimedJob Pomelo ...

  4. 1.jvm思维导图

    点击图片可查看高清图

  5. Java开发笔记(一百一十五)使用Socket开展文件传输

    前面介绍了怎样通过Socket在客户端与服务端之间传输文本,当然Socket也支持在客户端与服务端之间传输文件,因为文件本身就是通过I/O流实现读写操作的,所以在套接字的输入输出流中传输文件真是再合适 ...

  6. 在window10安装Mysql

    一:下载 1.1下载地址:https://dev.mysql.com/downloads/mysql/ 1.2解压 D:\InstallSoftWare\MYSQL 2环境变量配置    path里添 ...

  7. Educational Codeforces Round 71

    https://www.cnblogs.com/31415926535x/p/11460682.html 上午没课,做一套题,,练一下手感和思维,,教育场的71 ,,前两到没啥,,后面就做的磕磕巴巴的 ...

  8. Linux进程的五个段

    目录 数据段 代码段 BSS段 堆(heap) 栈 数据段 用来存放可执行文件中已初始化的全局变量,换句话说就是存放程序静态分配的变量和全局变量: 代码段 代码段是用来存放可执行文件的操作指令,也就是 ...

  9. egit报错:cannot open git-upload-pack

    第一次通过eclipse导入github 项目,按照百度步骤进行操作,发现不能连接 github,cannot open git-upload-pack. 报错原因通过 eclipse 日志排查报错 ...

  10. treeMultiselect 去掉勾选项

    场景描述:弹窗,显示树形结构,节点层次可变(可只有一级节点,也可是多级节点),限制只能选择一个节点! 1.修改jquery.tree-multiselect.min.js 文件 2.前台页面 参考代码 ...