最后块是否真的需要清理代码(如关闭流)?

Ank*_*kit 8 java exception-handling try-catch-finally

我很困惑为什么我需要将清理代码放在一个finally块中关闭流.

我已经读过finally块中的代码无论如何都会运行(是否存在异常); 并且在finally块运行之后,该方法的其余部分继续.

我的问题是:如果方法的其余部分必须继续,那么为什么我不在函数中的try/catch块之后放入清理代码?

Ste*_*n C 10

我的问题是; 如果方法的其余部分必须继续,那么为什么我不在函数中的try/catch块之后放置清理代码.

基本上,像这样:

InputStream is = ...
try {
   // use stream
} catch (IOException ex) {
   // report / recover
}
is.close();
Run Code Online (Sandbox Code Playgroud)

但是如果该// use stream部分抛出不同的(例如未经检查的)异常会发生什么?还是// report / recover代码?在任何一种情况下,close()呼叫都不会发生.(如果这些块中有break或者return声明怎么办?)

理论上可以这种方式实现它.问题是确保代码始终(即始终)运行.如果没有抓住一大堆你不应该抓住的例外情况,那么很难做到这一点......如果你抓住它就无法妥善处理.

总而言之,finally是更好的解决方案.

  • 它比你正确处理这种情况需要做的卷积更简单,并且
  • 它比典型的半心半意的尝试更可靠.

如果你可以使用新的Java 7"try with resources"形式,它会更简单/更可靠,其中finally自动处理.


我想补充一点,你对finally子句执行时的描述有点不准确.实际上,finally无论try块如何终止,都会执行该块,包括:

  • try块块掉落时,
  • 当它抛出一个异常时......无论异常是否在这个级别被捕获,或者
  • 当它执行一个return,continuebreak.

实际上,块执行的唯一情况finallytry块调用System.exit()或JVM崩溃.(或者,如果它进入无限循环...)


mik*_*era 3

如果抛出未捕获的异常,finally 块将始终运行,但该方法中的其余代码将被跳过。

因此,如果您将清理代码放在finally块之后,那么如果出现异常,它就不会被调用。

  • 正确的。如果捕获并处理异常,则执行将正常继续。但即使您确定会捕获所有异常(一个危险的假设......),将清理代码放在“finally”块中仍然是一个很好的做法。 (2认同)