如何仅使用 try-catch-finally 构造用两个资源重写 try-with-resources?

Posted

技术标签:

【中文标题】如何仅使用 try-catch-finally 构造用两个资源重写 try-with-resources?【英文标题】:How to rewrite try-with-resources with two resources using only try-catch-finally construction? 【发布时间】:2017-12-25 00:23:31 【问题描述】:

如何重写以下代码

try (A a = new A(); B b = new B()) 
//useful work here

catch (Exception e) 
//other code

使用 try-catch-finally 构造?

如果我们只创建一个资源,有一个很好的链接here。

不幸的是,当我们创建多个资源时,我不明白如何概括这一点。

我不明白的一件事是,我们如何识别 a 发生了某些事情而 'b' 没有发生,反之亦然。

【问题讨论】:

docs.oracle.com/javase/tutorial/essential/exceptions/… - 如果特定语句需要单独的 catch 语义处理,则可能应该有多个 try..catch 块。 Close multiple resources with AutoCloseable (try-with-resources)的可能重复 @SurfMan 不,他只需要 try-catch-finally 构造 @SurfMan 您链接的问题与我的问题完全无关。 @SurfMan 我想你没有得到这个问题! 【参考方案1】:

没有一般规则,但您必须确保尝试关闭您打开的所有资源,即使不知道发生了什么以及在哪个资源中。

 void test() throws Exception 
    A a = null;
    B b = null;

    Exception myException = null;
    try 
        a = new A();
        b = new B();
        //useful work here
     catch (Exception e) 
        myException = e;
        throw e;
     finally 
        Throwable tA = handleCloaseable(a);
        Throwable tB = handleCloaseable(b);

        boolean throwIt = false;
        if (myException == null && tA != null || tB != null) 
            myException = new Exception();
            throwIt = true;
        

        if (tA != null) 
            myException.addSuppressed(tA);
        
        if (tB != null) 
            myException.addSuppressed(tB);
        

        if (throwIt) 
            throw myException;
        
    


Throwable handleCloaseable(AutoCloseable e) // your resources must implements AutoCloseable or Closeable
    if (e != null) 
        try 
            e.close();
         catch (Throwable t) 
            return t;
        
    
    return null;

如果您尝试关闭资源时发生任何异常,请创建新的Exception(如果不存在)并在您尝试使用 addSuppressed 关闭时添加异常

【讨论】:

这根本不是关于 try-with-resources 的答案。 请仔细阅读问题,他需要将try-with-resources的形式转换为try-catch-finally!。 我看错了问题,抱歉。我明白这是反过来的。我不应该在平安夜回答 SO :) 没问题 :),我们来帮忙。 我很害怕,但是您的代码中不会抑制某些异常吗?在我链接方法addSuppresed的问题中,仅用于这种情况,即在创建对象时出现异常,在工作时出现异常。而且我想throw 异常,而不是记录错误。那么你能修改你的答案吗?

以上是关于如何仅使用 try-catch-finally 构造用两个资源重写 try-with-resources?的主要内容,如果未能解决你的问题,请参考以下文章

try-catch-finally

Java中使用try-catch-finally处理IO流中的异常

(34)C#里使用try-catch-finally

C++11接口纯虚析构函数

捕获异常try-catch-finally

try-catch-finally 中哪个部分可以省略?try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?