Try-with-resources

Try-with-resources是Java7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源。

利用Try-Catch-Finally管理资源(旧的代码风格)

在Java7以前,程序中使用的资源需要被明确地关闭,这个体验有点繁琐。

下面的方法读取文件,然后用System.out打印:

private static void printFile() throws IOException {
InputStream input = null;
try {
input = new FileInputStream("file.txt");
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
} finally {
if(input != null){
input.close();
}
}
}

上面代码中黑体字的程序可能会抛出异常。正如你所看到的,try语句块中有3个地方能抛出异常,finally语句块中有一个地方会能出异常。

不论try语句块中是否有异常抛出,finally语句块始终会被执行。这意味着,不论try语句块中发生什么,InputStream 都会被关闭,或者说都会试图被关闭。如果关闭失败,InputStream’s close()方法也可能会抛出异常。

假设try语句块抛出一个异常,然后finally语句块被执行。同样假设finally语句块也抛出了一个异常。那么哪个异常会根据调用栈往外传播?

即使try语句块中抛出的异常与异常传播更相关,最终还是finally语句块中抛出的异常会根据调用栈向外传播。

在Java7中,对于上面的例子可以用try-with-resource 结构这样写:

private static void printFileJava7() throws IOException {

    try(FileInputStream input =
new FileInputStream("file.txt")) { int data = input.read(); while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
}

注意方法中的第一行:

try(FileInputStream input = new FileInputStream("file.txt")) {

这就是try-with-resource 结构的用法。FileInputStream 类型变量就在try关键字后面的括号中声明。而且一个FileInputStream 类型被实例化并被赋给了这个变量。

当try语句块运行结束时,FileInputStream 会被自动关闭。这是因为FileInputStream 实现了java中的java.lang.AutoCloseable接口。所有实现了这个接口的类都可以在try-with-resources结构中使用。

当try-with-resources结构中抛出一个异常,同时FileInputStreami被关闭时(调用了其close方法)也抛出一个异常,try-with-resources结构中抛出的异常会向外传播,而FileInputStreami被关闭时抛出的异常被抑制了。这与文章开始处利用旧风格代码的例子(在finally语句块中关闭资源)相反。

使用多个资源

你可以在块中使用多个资源而且这些资源都能被自动地关闭。下面是例子:

private static void printFileJava7() throws IOException {

    try(FileInputStream input = new FileInputStream("file.txt"); BufferedInputStream bufferedInput = new BufferedInputStream(input))
{ int data = buffereInput.read();
while(data != -1){
System.out.println( (char) data);
data = bufferedInput.read();
}
}
}

上面的例子在try关键字后的括号里创建了两个资源——FileInputStream 和BufferedInputStream。当程序运行离开try语句块时,这两个资源都会被自动关闭。

这些资源将按照他们被创建顺序的逆序来关闭。首先BufferedInputStream 会被关闭,然后FileInputStream会被关闭。

自定义AutoCloseable 实现

这个try-with-resources结构里不仅能够操作java内置的类。你也可以在自己的类中实现java.lang.AutoCloseable接口,然后在try-with-resources结构里使用这个类。

AutoClosable 接口仅仅有一个方法,接口定义如下:

public interface AutoClosable{
public void close() throws Exception;
}

任何实现了这个接口的方法都可以在try-with-resources结构中使用。下面是一个简单的例子:

public class MyAutoClosable implements AutoClosable{

    public void doIt(){
System.out.println("MyAutoClosable doing it!");
} @Override
public void close() throws Exception{
System.out.println("MyAutoCloseable Closed!");
}
}

doIt()是方法不是AutoClosable 接口中的一部分,之所以实现这个方法是因为我们想要这个类除了关闭方法外还能做点其他事。

下面是MyAutoClosable 在try-with-resources结构中使用的例子:

private static void myAutoClosable() throws Exception{
try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
myAutoClosable.doIt();
}
}

当方法myAutoClosable.doIt()被调用时,下面是打印到System.out的输出:

MyAutoClosable doing it!
MyAutoClosable closed!

通过上面这些你可以看到,不论try-catch中使用的资源是自己创造的还是java内置的类型,try-with-resources都是一个能够确保资源能被正确地关闭的强大方法。

Java使用Try with resources自动关闭资源的更多相关文章

  1. maven工程,java代码加载resources下面资源文件的路径

    1 通过类加载器加载器, 1. URL resource = TestMain.class.getResource("/18500228040.txt");File file = ...

  2. java 自动关闭资源的try语句

    Java 7简化资源清理(try-with-resources)自动关闭资源的try语句 自动关闭资源格式: try( )//此处多了圆括号,()圆括号内写打开资源的代码,在这里创建的对象必须实现Au ...

  3. (转)java 从jar包中读取资源文件

    (转)java 从jar包中读取资源文件 博客分类: java   源自:http://blog.csdn.net/b_h_l/article/details/7767829 在代码中读取一些资源文件 ...

  4. Java 程序员必须收藏的资源大全

    Java 程序员必须收藏的资源大全 Java(27) 古董级工具 这些工具伴随着Java一起出现,在各自辉煌之后还在一直使用. Apache Ant:基于XML的构建管理工具.官网 cglib:字节码 ...

  5. maven项目没有src/test/java和src/test/resources目录问题解决

    新建maven项目,如下图示: 只有src/main/java和src/main/resources两个目录,而没有src/test/java和src/test/resources,于是第一反应是没有 ...

  6. 使用java调用fastDFS客户端进行静态资源文件上传

    一.背景 上篇博客我介绍了FastDFS的概念.原理以及安装步骤,这篇文章我们来聊一聊如何在java中使用FastDFSClient进行静态资源的上传. 二.使用步骤 1.开发环境 spring+sp ...

  7. Java Learning Path(五)资源篇

    Java Learning Path(五)资源篇 1. http://java.sun.com/ (英文) Sun的Java网站,是一个应该经常去看的地方.不用多说. 2.http://www-900 ...

  8. Java后端完整学习路线及资源记录

    Java后端完整学习路线及资源记录 Java语法基础 书籍教程: 视频教程: IDEA的使用 视频教程:JAVA开发利器-IntelliJ IDEA使用教程 Servlet和Web基础 书籍教程: 视 ...

  9. [转] Java 使用Try-with-resources自动关闭资源

    [From] https://blog.csdn.net/wtopps/article/details/71108342 Try-with-resources Try-with-resources是J ...

随机推荐

  1. 译MassTransit 创建消息消费者

    创建消息消费者一个消息消费者是一个 可以消费一个或多个消息类型的类,指定IConsumer<T>接口,T为消息类型 public class UpdateCustomerConsumer ...

  2. poj~1236 Network of Schools 强连通入门题

    一些学校连接到计算机网络.这些学校之间已经达成了协议: 每所学校都有一份分发软件的学校名单("接收学校"). 请注意,如果B在学校A的分发名单中,则A不一定出现在学校B的名单中您需 ...

  3. sql复杂案例

    工作中往往会遇到非常棘手的数据查询,运营人员不知道你的数据库表是如何设计的,也不知道你的数据库记录了啥数据,他只知道自己需要看什么数据,甚至有些数据根本就不存在. 单表查询的难度: 一张数据库的表ta ...

  4. TestNG详解-深度好文

    转自: https://blog.csdn.net/lykangjia/article/details/56485295 TestNG详解-深度好文 2017年02月22日 14:51:52 阅读数: ...

  5. TestNG exception

    以下内容引自: https://howtodoinjava.com/testng/testng-expected-exception-and-expected-message-tutorial/ Ho ...

  6. poj 3243 扩展BSGS

    每次把gcd(a,c)提到前面,直到a,c互质,然后就是普通BSGS了 #include<cstdio> #include<cstring> #include<iostr ...

  7. BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划

    BZOJ_4197_[Noi2015]寿司晚宴_状态压缩动态规划 Description 为了庆祝 NOI 的成功开幕,主办方为大家准备了一场寿司晚宴.小 G 和小 W 作为参加 NOI 的选手,也被 ...

  8. Python Django 2.2登录功能_2

    #Now 让我们继续对上篇的登录进行操作 #对于csrf,以后再开篇章记录 #修改index.html <form method="post" action="/l ...

  9. ASP.NET Core的实时库: SignalR简介及使用

    大纲 本系列会分为2-3篇文章. 第一篇介绍了SignalR的预备知识和原理 本文介绍SignalR以及ASP.NET Core里使用SignalR. 本文的内容: 介绍SignalR 在ASP.NE ...

  10. MongoDB面试题

    1.什么是MongoDB MongoDB是一个文档数据库,提供好的性能,领先的非关系型数据库.采用BSON存储文档数据.BSON()是一种类json的一种二进制形式的存储格式,简称Binary JSO ...