java - 如果关闭资源失败,java 会做什么?

标签 java resources try-catch finally

在过去,我必须使用一些资源,我在 try block 中声明它,在 try block 中创建它,并在 finally block 中关闭它。对于关闭失败的情况,它被放入内部 try block 中。

Resource r=null;
try{
   r=new Resource();
   use(r); 
} 
catch(){
    outputAndLog(something);
}
finally{
    if(r != null){
        try{
        }
        catch(){
            outputAndLog(somethingElse);
        }
    }
}

现在我们可以使用

try(Resource r = new Resource()){

Java 语法。 block 最终对我们来说变得不可见。但是里面有什么?我的意思是,如果关闭失败会怎样?

最佳答案

资源:Link


首先,try-with-resources 实际上并不处理任何Exceptions(就像在您的代码中通过日志记录完成的那样)。基本上它编码try-catch-finally构造抛出的可能多个Exceptions到一个可处理的对象——一个Exception 包含被抑制的 Exceptions

如果 try block 抛出一个 Exception,资源将被关闭并且产生的 Exception 将被抑制。因此,抛出的 Exception 对象将引用被抑制的 Exception
如果 try block 没有抛出 Exception,资源将被关闭并重新抛出产生的 Exception

因此我们可以得出结论,您的示例是等效的:
当使用 try-catch-finally 时,成功处理后关闭导致的 Exception 将被视为“只是一个关闭错误”,而使用 try-with- resources 语句这样的Exception 将与实际处理中发生的Exception 同等处理。

tl;dr
如果处理资源关闭包括更多东西try-with-resources 语句可能会产生旧的try-catch-finally< 不会遇到的错误。此类内容的一个示例是jdbc 连接的提交和回滚。


因此,最终生成一些代码,用于

try(Resource resource = new Resource()){
    // other code
}

确切的等价物是:

{
    Resource resource = null;
    Exception exc = null;
    try {
        resource = new Resource();
        // other code
    } catch (Exception e) {
        exc = e;
        throw e;
    } finally {
        if (resource != null) {
            if (exc != null) {
                try {
                    resource.close();
                } catch (Throwable t) {
                    exc.addSuppressed(t);
                }
            } else {
                resource.close();
            }
        }
    }
}

关于java - 如果关闭资源失败,java 会做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47501757/

相关文章:

Java - 连接到 MYSQL 数据库 try/catch 的代码出错?

java - 在 RESTLet DAO Client Server Architecture In Java 中配置回退数据源

Java 发生在关系 invokeAndWait 之前

java - Java 中的资源加载无法正常工作

uwp - 如何避免 UWP 应用程序中的重复条目构建错误?

java - 使用 throw/catch 的鼠标监听器 (java)

java - JUnit:创建JavaBean时测试int类型的ID是否为null

java - 如何在processingJS中创建一个空的int数组?

ruby-on-rails - 如何在 Rails 中为具有多个关键字段的资源定义 RESTful 路由?

java - 使用循环进行输入验证和异常处理