Java 7:尝试资源

本文研究try-with-resources语句的用法。 这是一个声明一个或多个资源的try语句。 资源是一个对象,程序完成后必须将其关闭。

try-with-resources语句可确保在语句末尾关闭每个资源。 任何实现java.lang.AutoCloseable或java.io.Closeable接口的对象都可以用作资源。

尝试使用资源 (在Java 7之前)处理SQL语句或ResultSet或Connection对象或其他IO对象之前,必须显式关闭资源。 所以一个人会写类似:

try{
  //Create a resource- R
} catch(SomeException e){
  //Handle the exception
} finally{
  //if resource R is not null then
  try{
    //close the resource
  }
  catch(SomeOtherException ex){
  }
}

我们必须显式关闭资源,从而添加更多代码行。 在极少数情况下,开发人员会忘记关闭资源。 因此,为了克服这些问题和其他问题,Java 7中引入了try-with-resources

让我们看一个示例,说明如何在Java 7之前的版本中使用try..catch…。让我创建2个自定义异常-ExceptionA和ExceptionB。 这些将在整个示例中使用。

public class ExceptionA extends Exception{
    public ExceptionA(String message){
        super(message);
    }
}
public class ExceptionB extends Exception{
    public ExceptionB(String message){
        super(message);
    }
}

让我们创建一些资源,例如OldResource,它有两种方法– doSomeWork():完成一些工作,close():完成关闭。 请注意,这描述了通用资源的使用-做一些工作,然后关闭资源。 现在,每个操作doSomeWork和close都会引发异常。

public class OldResource{
    public void doSomeWork(String work) throws ExceptionA{
        System.out.println("Doing: "+work);
        throw new ExceptionA("Exception occured while doing work");
    }
    public void close() throws ExceptionB{
        System.out.println("Closing the resource");
        throw new ExceptionB("Exception occured while closing");
    }
}

让我们在示例程序中使用此资源:

public class OldTry {
    public static void main(String[] args) {
        OldResource res = null;
        try {
            res = new OldResource();
            res.doSomeWork("Writing an article");
        } catch (Exception e) {
            System.out.println("Exception Message: "+
                      e.getMessage()+" Exception Type: "+e.getClass().getName());
        } finally{
            try {
                res.close();
            } catch (Exception e) {
                System.out.println("Exception Message: "+
                         e.getMessage()+" Exception Type: "+e.getClass().getName());
            }
        }
    }
}

输出:

Doing: Writing an article
Exception Message: Exception occured while doing work Exception Type: javaapplication4.ExceptionA
Closing the resource
Exception Message: Exception occured while closing Exception Type: javaapplication4.ExceptionB

该程序很简单:创建一个新资源,使用它,然后尝试关闭它。 可以看看那里多余的代码行数。

现在,让我们使用Java 7的try-with-resource结构实现相同的程序。 为此,我们需要一个新资源– NewResource。 在Java 7中,新接口为java.lang.AutoCloseable 。 那些需要关闭的资源将实现此接口。 所有较旧的IO API,套接字API等都实现了Closeable接口-这意味着可以关闭这些资源。 使用Java 7, java.io.Closeable实现AutoCloseable 。 因此,一切正常,而不会破坏任何现有代码。

下面的NewResource代码:

public class NewResource implements AutoCloseable{
    String closingMessage;
 
    public NewResource(String closingMessage) {
        this.closingMessage = closingMessage;
    }
 
    public void doSomeWork(String work) throws ExceptionA{
        System.out.println(work);
        throw new ExceptionA("Exception thrown while doing some work");
    }
    public void close() throws ExceptionB{
        System.out.println(closingMessage);
        throw new ExceptionB("Exception thrown while closing");
    }
 
    public void doSomeWork(NewResource res) throws ExceptionA{
        res.doSomeWork("Wow res getting res to do work");
    }
}

现在,使用try-with-resource在示例程序中使用NewResource:

public class TryWithRes {
    public static void main(String[] args) {
        try(NewResource res = new NewResource("Res1 closing")){
            res.doSomeWork("Listening to podcast");
        } catch(Exception e){
            System.out.println("Exception: "+
       e.getMessage()+" Thrown by: "+e.getClass().getSimpleName());
        }
    }
}

输出:

Listening to podcast
Res1 closing
Exception: Exception thrown while doing some work Thrown by: ExceptionA

上面要注意的一件事是,关闭方法抛出的异常被worker方法抛出的异常所抑制。

因此,您可以立即注意到这两种实现之间的差异,一种实现最终使用try ... catch ...,另一种使用try-with-resource。 在上面的示例中,仅一个资源被声明为已使用。 一个人可以在try块中声明和使用多个资源,也可以嵌套这些try-with-resources块。

随之,在java.lang.Throwable类中添加了一些新方法和构造函数,所有这些方法都与抑制与其他异常一起抛出的异常有关。 最好的例子是-try块抛出的ExceptionA会被finally(关闭资源时)抛出的ExceptionB抑制,这是Java 7之前的行为。

但是,对于Java 7,抛出的异常会跟踪它在被捕获/处理的过程中被抑制的异常。 因此,前面提到的示例可以重新陈述如下。 由close方法抛出的ExceptionB被添加到由try块抛出的ExceptionA的抑制异常列表中。

让我用以下示例说明您嵌套的try-with-resources和Suppressed异常。

嵌套的尝试资源

public class TryWithRes {
    public static void main(String[] args) {
        try(NewResource res = new NewResource("Res1 closing");
            NewResource res2 = new NewResource("Res2 closing")){
            try(NewResource nestedRes = new NewResource("Nestedres closing")){
                nestedRes.doSomeWork(res2);
            }
        } catch(Exception e){
            System.out.println("Exception: "+
      e.getMessage()+" Thrown by: "+e.getClass().getSimpleName());
        }
 
    }
}

上面的输出将是:

Wow res getting res to do work
Nestedres closing
Res2 closing
Res1 closing
Exception: Exception thrown while doing some work Thrown by: ExceptionA

注意关闭资源的顺序,最新的优先。 还要注意,抑制了每个close()操作引发的异常。

让我们看看如何检索被抑制的异常:

禁止的异常

public class TryWithRes {
    public static void main(String[] args) {
        try(NewResource res = new NewResource("Res1 closing");
            NewResource res2 = new NewResource("Res2 closing")){
            try(NewResource nestedRes = new NewResource("Nestedres closing")){
                nestedRes.doSomeWork(res2);
            }
        } catch(Exception e){
            System.out.println("Exception: "+
      e.getMessage()+" Thrown by: "+e.getClass().getSimpleName());
            if (e.getSuppressed() != null){
                for (Throwable t : e.getSuppressed()){
                    System.out.println(t.getMessage()+
                               " Class: "+t.getClass().getSimpleName());
                }
            }
        }
 
    }
}

上面代码的输出:

Wow res getting res to do work
Nestedres closing
Res2 closing
Res1 closing
Exception: Exception thrown while doing some work Thrown by: ExceptionA
Exception thrown while closing Class: ExceptionB
Exception thrown while closing Class: ExceptionB
Exception thrown while closing Class: ExceptionB

getSuppressed()方法用于检索被抛出的异常阻止的异常。 还向Throwable类添加了新的构造函数,该构造函数可用于启用或禁用异常抑制。 如果禁用,则不会跟踪任何抑制的异常。

参考: Java 7项目硬币: Try -with-resources,以及我们的JCG合作伙伴 Mohamed SanaullaExperiences Unlimited Blog 上的示例进行了解释

相关文章 :

翻译自: https://www.javacodegeeks.com/2011/07/java-7-try-with-resources-explained.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值