当前位置:  开发笔记 > 编程语言 > 正文

在finally块中抛出异常

如何解决《在finally块中抛出异常》经验,为你挑选了5个好方法。

是否有一种优雅的方法来处理finally块中抛出的异常?

例如:

try {
  // Use the resource.
}
catch( Exception ex ) {
  // Problem with the resource.
}
finally {
   try{
     resource.close();
   }
   catch( Exception ex ) {
     // Could not close the resource?
   }
}

你如何避免try/ catchfinally街区?



1> Darron..:

我通常这样做:

try {
  // Use the resource.
} catch( Exception ex ) {
  // Problem with the resource.
} finally {
  // Put away the resource.
  closeQuietly( resource );
}

别处:

protected void closeQuietly( Resource resource ) {
  try {
    if (resource != null) {
      resource.close();
    }
  } catch( Exception ex ) {
    log( "Exception during Resource.close()", ex );
  }
}


检查null并不总是多余的.可以将"resource = new FileInputStream("file.txt")"视为try的第一行.此外,这个问题不是关于面向方面的编程,许多人不使用.但是,通过显示日志语句,可以最简单地处理不应忽略异常的概念.
如果你需要在同一个类中的几个地方使用成语,那么函数很方便.
是的,我使用了一个非常相似的成语.但我没有为此创建功能.

2> CJS..:

我通常使用以下closeQuietly方法之一org.apache.commons.io.IOUtils:

public static void closeQuietly(OutputStream output) {
    try {
        if (output != null) {
            output.close();
        }
    } catch (IOException ioe) {
        // ignore
    }
}


是的,Closeable非常好.遗憾的是很多事情(比如JDBC资源)都没有实现它.
您可以使用Closeable public static void closeQuietly(Closeable closeable){使此方法更通用

3> Kevin Wong..:

如果你正在使用Java 7和resourceimplements AutoClosable,你可以这样做(使用InputStream作为例子):

try (InputStream resource = getInputStream()) {
  // Use the resource.
}
catch( Exception ex ) {
  // Problem with the resource.
}



4> MB...:

可以说有点超过顶部,但是如果你让异常冒出来并且你不能在你的方法中记录任何东西(例如因为它是一个库而你宁愿让调用代码处理异常和日志记录)也许有用:

Resource resource = null;
boolean isSuccess = false;
try {
    resource = Resource.create();
    resource.use();
    // Following line will only run if nothing above threw an exception.
    isSuccess = true;
} finally {
    if (resource != null) {
        if (isSuccess) {
            // let close throw the exception so it isn't swallowed.
            resource.close();
        } else {
            try {
                resource.close();
            } catch (ResourceException ignore) {
                // Just swallow this one because you don't want it 
                // to replace the one that came first (thrown above).
            }
        }
    }
}

更新:我看着这更多了一下,发现从别人一个伟大的博客文章谁显然已经想过这个比我:http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make -mess-of-stream.html 他更进了一步,将两个例外合并为一个,我认为在某些情况下它是有用的.



5> Soroosh..:

从Java 7开始,您不再需要显式关闭finally块中的资源,而是可以使用try -with-resources语法.try-with-resources语句是一个声明一个或多个资源的try语句.资源是在程序完成后必须关闭的对象.try-with-resources语句确保在语句结束时关闭每个资源.实现java.lang.AutoCloseable的任何对象(包括实现java.io.Closeable的所有对象)都可以用作资源.

假设以下代码:

try( Connection con = null;
     Statement stmt = con.createStatement();
     Result rs= stmt.executeQuery(QUERY);)
{  
     count = rs.getInt(1);
}

如果发生任何异常,将按照创建它们的相反顺序在这三个资源中的每一个上调用close方法.这意味着将首先为ResultSetm调用close方法,然后调用Statement,最后调用Connection对象.

同样重要的是要知道自动调用close方法时发生的任何异常都会被抑制.可以通过Throwable类中定义的getsuppressed()方法检索这些抑制的异常.

资料来源:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html


如果try块中的部分正常完成但close方法没有,则使用try-with-resources会在关闭时抛出异常,这与OP代码不同.在不承认行为改变的情况下推荐它作为替代品似乎可能具有误导性.
试试我描述的情况.try块正常完成,close抛出一些东西.并重新读取您发布链接的页面,抑制仅适用于try块抛出的内容.
推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有