将try catch finally块放置在另一个finally块内部

28
 try {
 } catch() {}
 finally {
     try {
     } catch() { }
     finally { }
 }

像上面那样编写代码是否好?


也许你可以阅读这个链接:https://dev59.com/0nM_5IYBdhLWcg3wiDuA - planetjones
5个回答

42

是的,你可以这样做。

事实上,在处理需要正确关闭的流时,这甚至是必需的:

InputStream in = /* ... */;
try {
} catch (...) {
} finally {
    try {
        in.close();
    } catch (...) {
    } finally {
    }
}

我没有看到任何情况下这会变成不良实践


好的例子。但我始终认为这是难以阅读的代码,并尝试创建一些实用程序方法或类,可以关闭具有空值检查的可关闭实例。 - Vladimir Ivanov

13

为了提高可读性,您可以将嵌套的try-catch分解为一个单独的方法,例如:

  try{
  }catch(){}
  finally{
    cleanup();
  }

第二个 try-catch 块可以放在 cleanup 方法内部。

为了支持 IO 包中的上述模式,JAVA6 引入了一个名为 Closeable 的新类,所有流都实现了它,以便您可以拥有如下单个 cleanup 方法:

public static boolean cleanup(Closeable stream)
{
try{
    stream.close();
    return true;
  }catch(){
    return false;
  }
}

3
最好能够避免使用它,但有时可能是必要的。如果您告诉我们更多关于为什么您认为需要这个的原因,我们可能能够给出更好的答案 :-)
考虑使用finally块提交事务的一个原因是,提交操作本身可能会抛出异常。
需要注意的是,在finally块中抛出的异常很容易掩盖先前在try块中抛出的异常,除非得到适当处理。因此,这种嵌套的try/catch块有时是可行的。然而,正如其他人所指出的那样,为了提高可读性,建议将finally块的内部提取到一个单独的方法中。

3

有些情况下,虽然不太美观,但你无法避免它。特别是在资源清理方面,当你有相关的资源,而清理其中一个资源会抛出异常时,就需要这么做。

JDBC代码中,典型的例子是整理 ResultSetStatementConnection 对象。关闭 ResultSet 可能会抛出异常,但我们仍然希望继续关闭 StatementConnection


2

看起来不太美观,但有时候这是必须的。根据代码情况,考虑使用第二个try-catch-finally块提取一个方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接