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

利用Try-Catch-Finally管理资源(旧的代码风格)
在java7以前,程序中使用的资源需要被明确地关闭,这个体验有点繁琐。

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

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

上面代码中黑体字的程序可能会抛出异常。正如你所看到的,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 = bufferedInput.read();
        while(data != -1){
            System.out.print((char) data);
    data = bufferedInput.read();
        }
    }
}

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

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

自定义AutoClosable 实现
这个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 AutoCloseable {

    public void doIt() {
        System.out.println("MyAutoClosable doing it!");
    }     @Override
    public void close() throws Exception {
        System.out.println("MyAutoClosable 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都是一个能够确保资源能被正确地关闭的强大方法。

Java7 新特性: try-with-resources的更多相关文章

  1. java7新特性之Try-with-resources (TWR)

    java7新特性之Try-with-resources (TWR) This change is easy to explain, but it has proved to have hidden s ...

  2. java7新特性之Diamond syntax

    java7新特性之Diamond syntax Java 7 also introduces a change that means less typing for you when dealing ...

  3. java7新特性 java8新特性

    Java 7 的7个新特性 Java7语法新特性 JAVA8 十大新特性详解 http://www.jb51.net/article/48304.htm

  4. Java7 新特性 数值文本表示法

    今天和大家分享下 java7中新特性-数值文本表示法 首先,在原来jdk1.6中 如果需要将一个二进制的数值转换成十进制的话,一般情况下都会以下面的代码方式去实现. public static voi ...

  5. java7 新特性 总结版

    Java7语法新特性: 前言,这是大部分的特性,但还有一些没有写进去,比如多核 并行计算的支持加强 fork join 框架:这方面并没有真正写过和了解.也就不写进来了. 1. switch中增加对S ...

  6. Java7新特性

    ① 新增了switch对字符串的支持,也就是说可以在switch之后直接使用字符串来进行判断,语法基本与Java7之前支持的语法一样. ② 对数值字面量的增强支持,首先是可以在源代码中直接使用二进制数 ...

  7. Java7 新特性 —— java.nio.file 文件操作

    本文部分摘自 On Java 8 自 Java7 开始,Java 终于简化了文件读写的基本操作,新增了 java.nio.file 库,通过与 Java8 新增的 stream 结合可以使得文件操作变 ...

  8. Java7 新特性 switch 可以使用String

    今天和大家分享下 在java7中可以使用String 作为switch 中的参数. 原来在java7之前,switch只能去接收一个 byte.char.short.int 类型 现在在java7中 ...

  9. Java之Java7新特性之try资源句式

    一.原来写法: static String readFirstLineFromFile(String path) throws IOException { BufferedReader br = nu ...

随机推荐

  1. 共用体union

    union共用体名 { 类型名 成员名1: 类型名 成员名2: …… 类型名 成员名n; } 由于各个成员变量在内存中都使用同一段存储空间,因此共用体变量的长度等于最长的成员长度,共用体的访问方式和结 ...

  2. Linux基础入门之vsFTP+MySQL/MariaDB认证实现虚拟用户配置详解

    https://www.dwhd.org/20150603_144841.html 摘要 VSFTP可以使用系统账户或者匿名账户登录,但是出于安全的考虑,通常建议使用vsftp虚拟账户来登录ftp服务 ...

  3. ssh证书免认证登录

    思路: 客户端私钥存放于客户端,/root/.ssh/id_rsa 将客户端公钥存放于要远程控制服务器上:将客户在公钥id_rsa.pub内容追加到 /root/.ssh/authorized_key ...

  4. bind智能DNS + bindUI管理系统

    bind UI 管理系统 https://github.com/cucker0/BindUI # bind安装 cd /usr/local/src wget http://ftp.isc.org/is ...

  5. OpenWrt路由器通过LuCI界面实现Guest SSID功能

    转自: http://blog.ltns.info/linux/guest_ssid_over_openwrt_router/ 之前尝试过 Tomato路由器设置VLAN实现Guest SSID功能, ...

  6. ES Route

    在ElaticSearch里面,路由功能算是一个高级用法,大多数时候我们用的都是系统默认的路由功能,一个es索引可以分多个shard和每个shard又可以有多个replia,默认情况下,elastic ...

  7. 关于zynq7 中MIO的理解

    关于zynq7 中MIO的理解 Zynq7000有54个MIO,分配在GPIO的Bank0和Bank1,属于PS部分,这些IO与PS直接相连,不需要添加引脚约束,MIO信号对PL部分是不可见的,对MI ...

  8. TouchSlide 插件参数

    TouchSlide 可以说是 SuperSlide 手机简化版,不同的地方在于: 1.TouchSlide是纯javascript开发的,不依赖任何js库,鉴于此,TouchSlide调用方法和Su ...

  9. [蓝桥杯]ALGO-49.算法训练_寻找数组中最大值

    题目描述: 问题描述 对于给定整数数组a[],寻找其中最大值,并返回下标. 输入格式 整数数组a[],数组元素个数小于1等于100.输出数据分作两行:第一行只有一个数,表示数组元素个数:第二行为数组的 ...

  10. VBA Dumper v0.1.4.2, 提取office文档中的VBA代码,监查宏病毒恢复代码(演示版

    http://club.excelhome.net/thread-970051-1-1.html VBA Dumper 0.1.4.2更新,填补国内同类程序空白 此程序为演示版,可以在无office的 ...