3.Try-with-resources in Java 7

try..with..resources是java7的一种新的异常处理机制,能够很容易的使用try…catch块正确关闭资源回收.

对于有资源回收管理的异常处理方式,老式学校的处理:

private static void printFile() throws IOException {
    InputStream input = null;

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

        int data = input.read();//2
        while(data != -1){
            System.out.print((char) data);
            data = input.read();//3
        }
    } finally {
        if(input != null){
            input.close();//4
        }
    }
}

有4处地方容易发生异常,你可以看到,三处在try块,1处在finally块.finally块总是会执行,不管try块是否有异常抛出,这意味着, inputstream是会关闭的或者说试图关闭.
inputstream的close() 方法意味着也会抛出异常,如果关闭失败了. 想象一下异常从try块跑出来,finally块会执行.当异常冲finally块抛出的时候,这个异常会不会上抛给访问栈?
从finally块抛出的异常会传播给访问栈,即使try块的异常可能是更相关的传播。

try-with-resources
在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-with-resources结构, 变量FileInputStream被声明在大括号里面,另外一FileInputStream是一个实例分配给一个变量.
当try块执行完成,FileInputStream将自动关闭.这是因为FileInputStream实现了java.lang.AutoCloseable接口.所有实现该接口的类都可以放在try-with-resources结构中.

如果一个异常从try-with-resources块中抛出,fileinputstream已经关闭了,try块中抛出的异常将抛到外层.异常会被抑制.这刚好和开头的案例相反(使用旧有异常处理).

使用多个资源
也可以使用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();
        }
    }
}

这个案例创建了两个资源通过try关键字后面的括号. FileInputStream 和 BufferedInputStream.两个资源都会在执行流离开try块后自动关闭.
资源会通过反向初始化顺序的关闭, BufferedInputStream 先关闭, FileInputStream后关闭.

自定义可关闭资源的实现
使用try-with-resources结构不仅仅适用于java内建类.也能通过实现java.lang.autocloseable接口实现自己类使用.
下面是AutoCloseable接口:


public interface AutoClosable {

    public void close() throws Exception;
}

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!");
    }
}

private static void myAutoClosable() throws Exception {

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

//console output
MyAutoClosable doing it!
MyAutoClosable closed!

你可以看到,try-with-resources是一个十分强大的方式确保使用在try-catch中的资源能正常关闭,不管这个资源时自己创建的还是java自带的组件.
译者:如果用户在使用一个类似于事务处理的业务时,可以通过实现该接口,完成一致性处理.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值