Try-with-resources 是 java 7 中的一个新的异常处理机制,它可以更容易的正确关闭在 try-catch 块中使用的资源。

资源管理与 Try-Catch-Finally,旧风格

在 java 7 之前,管理需要明确关闭的资源是相当繁琐的。

看看下面的方法,它读取一个文件并将其打印到 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();
}
}
}

在上面的代码中有四处可能抛出异常new FileInputStream("file.txt");int data = input.read();data = input.read();input.close();

不管try块是否抛出异常,finally块总是被执行。也就是说,无论try快种发生了什么,InputStream都将被关闭。然而如果关闭失败,close()方法也有可能抛出异常。

思考一下,如果try块内抛出一个异常,finally块也抛出一个异常,你认为哪个异常会在调用堆栈中传递。

finally块中抛出的异常将会在调用堆栈中传递,即使try块抛出的异常可能与传递相关。

Try-with-resources

在 Java 7 中你可以使用 Try-with-resources 结构来编写上面示例中的代码:

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-resources结构。在 try 关键字后面的括号中声明并实例化FileInputStream

当 try 块结束时,FileInputStream将自动关闭。因为FileInputStream 实现了java.lang.AutoCloseable接口,所有实现改接口的类都可以使用try-with-resources结构。

如果一个异常从try-with-resources块中抛出,并且当FileInputStream被关闭时(调用close()时),在 try 块中的异常江北抛出到外部世界,FileInputStream关闭时抛出的异常被抑制。这与前面的示例情况正好相反。

管理多个资源

你可以在try-with-resources块中使用多个资源,并将它们全部自动关闭。下面是一个示例:

private static void printFileJava7() throws IOException {

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

这个例子在括号中创建了两个资源,一个FileInputStream和一个BufferedInputStream

当执行完 try 块时,这两个块都将被关闭。

这些资源将按照他们在括号内创建/列出顺序相反的顺序关闭,也就是先关闭BufferedInputStream,然后关闭FileInputStream

自定义 AutoClosable 实现

try-with-resources结构不仅适用于 java 内置类,你也可以在自己的类中实现java.lang.AutoCloseable接口,便可使用try-with-resources接口。

AutoClosable接口中只有一个名为close()的方法,接口如下所示:

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

任何实现此接口的类都可以与try-with-resources一起使用。下面是一个简单的示例:

public class MyAutoClosable implements AutoCloseable {

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

doIt()方法不是AutoClosable接口的一部分,它之所以存在是因为我们想要做的不仅仅是关闭对象。

下面是MyAutoClosabletry-with-resources结构一起使用的示例:

private static void myAutoClosable() throws Exception {

    try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
myAutoClosable.doIt();
}
}

当我们调用myAutoClosable()方法时,输出如下:

MyAutoClosable doing it!
MyAutoClosable closed!

正如你所看到的,无论这些资源是你自己所创建还是 Java 的内置组件,try-with-resources都是确保正确关闭try-catch块内部使用的资源的一种强大的方式。

原文链接:http://tutorials.jenkov.com/java-exception-handling/try-with-resources.html#using-multiple-resources

Java Try-with-resources的更多相关文章

  1. Java项目访问resources文件

    最近在对接支付宝支付的开发,需要取到支付的RSA公钥和私钥.于是把公钥和私钥加到resources文件夹里.但是不知道怎么读到这两个文件,也就是不知道路径怎么写.于是网上搜索了下如何获取工作路径,Sy ...

  2. Java工程读取resources中资源文件路径问题

    正常在Java工程中读取某路径下的文件时,可以采用绝对路径和相对路径,绝对路径没什么好说的,相对路径,即相对于当前类的路径.在本地工程和服务器中读取文件的方式有所不同,以下图配置文件为例. 本地读取资 ...

  3. 普通java工程的resources目录寻址

    问题: 普通java工程的src/main/resources目录下的配置文件如何寻址 在src/main/java目录下的代码中如何访问src/main/resources目录下的配置文件? Mav ...

  4. Java 如何读取resources

    Sample in Github 1.一般使用Maven创建Java工程,代码文件在src/main/java文件夹中,资源文件在src/main/resources文件夹中,Java代码为什么可以读 ...

  5. Java项目读取resources资源文件路径那点事

    今天在Java程序中读取resources资源下的文件,由于对Java结构了解不透彻,遇到很多坑.正常在Java工程中读取某路径下的文件时,可以采用绝对路径和相对路径,绝对路径没什么好说的,相对路径, ...

  6. Java – Try with Resources

    1.介绍 Java 7中引入的对try-with-resources的支持使我们能够声明将在try块中使用的资源,并确保在执行该块后将关闭资源. ⚠️:声明的资源必须实现AutoCloseable接口 ...

  7. java web中resources路径

    UserBean.class.getClassLoader().getResource(filePath).getPath() 或者 Thread.currentThread().getContext ...

  8. [Java] 在 jar 文件中读取 resources 目录下的文件

    注意两点: 1. 将资源目录添加到 build path,确保该目录下的文件被拷贝到 jar 文件中. 2. jar 内部的东西,可以当作 stream 来读取,但不应该当作 file 来读取. 例子 ...

  9. Java获取/resources目录下的资源文件方法

    Web项目开发中,经常会有一些静态资源,被放置在resources目录下,随项目打包在一起,代码中要使用的时候,通过文件读取的方式,加载并使用: 今天总结整理了九种方式获取resources目录下文件 ...

  10. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

随机推荐

  1. USART_GetITStatus和USART_GetFlagStatus的区别

    USART_GetITStatus()和USART_GetFlagStatus()的区别 都是访问串口的SR状态寄存器,唯一不同是,USART_GetITStatus()会判断中断是否开启,如果没开启 ...

  2. Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI

    目录 引言 Search APIs Search API Search Request 可选参数 使用 SearchSourceBuilder 构建查询条件 指定排序 高亮请求 聚合请求 建议请求 R ...

  3. 【Orleans开胃菜系列2】连接Connect源码简易分析

    [Orleans开胃菜系列2]连接Connect源码简易分析 /** * prism.js Github theme based on GitHub's theme. * @author Sam Cl ...

  4. Activity猫的一生-故事解说Activity生命周期

    大家好,关于Android中Activity的生命周期,网上大多数文章基本都是直接贴图.翻译API,比较笼统含糊不清. 我就用故事来说一说: 有个人叫User,TA养了几只猫,有只猫叫Activity ...

  5. 前端项目模块化的实践3:使用 TypeScript 的收益

    以下是关于前端项目模块化的实践,包含以下内容: 搭建 NPM 私有仓库管理源码及依赖: 使用 Webpack 打包基础设施代码: 使用 TypeScript 编写可靠类库 使用 TypeScript ...

  6. 移动端jq及zepto事件绑定

    最近做移动端网页,用到了zepto.js , 其大致用法跟 jquery 差不多,但是在时间绑定的时候被困了好久的坑. 这里说的主要是给未来元素绑定事件.未来元素:这里指的是通过 ajax 请求得到数 ...

  7. java Script复习总结

    一:基础知识 1.JavaScript语言的历史 l  早期名称:livescript l  开发公司:网景公司(netscape) 2.JavaScript语言的基本特点 l  基于对象 l  事件 ...

  8. net面试宝典

    ASP.NET常见面试题及答案 1. 简述 private. protected. public. internal 修饰符的访问权限. 答 . private : 私有成员, 在类的内部才可以访问. ...

  9. python 游戏(船只寻宝)

    1. 游戏思路和流程图 实现功能:船只在可以在大海上移动打捞宝藏,船只可以扫描1格范围内的宝藏(后续难度,可以调整扫描范围,可以调整前进的格数) 游戏流程图 2. 使用模块和游戏提示 import r ...

  10. Vivado绑定外部verilog编辑器

    前言 由于Vivado自带的verilog编辑器确实难用,写起来效率不高,因而寻找到了以下教程. 解决方案 引用sublime作为vivado外部verilog编辑器 sublime text中文编码 ...