最后有时会让我感到困惑

今天在大学里,我们聊了一会儿,和.我对这两个例子感到困惑:trycatchfinally

PrintWriter out = null;
try {
  out = new PrintWriter(...); // We open file here
} catch (Exception e) {
  e.printStackTrace();
} finally { // And we close it here
  out.close();
}

关闭文件和我们只是以这种方式关闭文件有什么区别:finally

PrintWriter out = null;
try {
  out = new PrintWriter(...); // We open file here
} catch (Exception e) {
  e.printStackTrace();
}
out.close();

catch 后的这段代码将始终执行。

你能给我一些很好的例子,说明我们何时使用和何时在捕获后放置代码之间的差异吗?我知道最终将始终执行,但程序也会在捕获块后继续运行。finally


答案 1

如果代码抛出 ,它仍然会有所不同。这不会捕获在代码中,因此之后的任何部分都不会被捕获。如果 它是 的一部分,即使对于 ,它仍将执行。Errortry/catch/finallyfinallyError

其次,如果由于某种原因引发异常(尽管这种情况非常罕见),同样的事情也会发生 - 仍将执行。e.printStackTrace()finally

一般来说,无论发生什么,释放资源都是非常安全的方式。自Java 7以来支持的try-with-resources更加安全,因为它可以轻松管理在关闭操作期间可能引发的多个异常。在此示例中,它看起来像:finally

try (PrintWriter out = new PrintWriter(...)) {
    // do whatever with out
}
catch (Exception e) {
    e.print... (whatever)
}
// no need to do anything else, close is invoked automatically by try block

编辑:还要注意,你的代码并不真正正确(无论哪个版本)。如果构造函数引发异常,则该行将在 上失败。PrintWriterout.close()NullPointerException


答案 2

如果块内发生未捕获的错误,或者即使块内发生错误,则捕获后的“代码段”不会执行,但块会执行。trycatchfinally

finally将始终执行。

从 Java 文档中可以看出:

最终块始终在 try 块退出时执行。这可确保即使发生意外异常,也会执行 finally 块。但最终不仅对异常处理有用 - 它允许程序员避免清理代码被返回,继续或中断意外绕过。将清理代码放在 finally 块中始终是一种很好的做法,即使预计不会出现异常也是如此。


推荐