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

时间:2012-08-20 10:02:47

标签: java exception-handling try-catch-finally

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

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

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

10 个答案:

答案 0 :(得分:10)

  

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

基本上,像这样:

InputStream is = ...
try {
   // use stream
} catch (IOException ex) {
   // report / recover
}
is.close();

但如果// use stream部分抛出不同的(例如未经检查的)异常,会发生什么?还是// report / recover代码?在任何一种情况下,close()调用都不会发生。 (如果这些块中有breakreturn语句会怎么样?)

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

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

  • 它比你正确处理这种情况需要做的回合更简单,
  • 它比典型的半心半意的尝试更可靠。

如果您可以使用新的Java 7“try with resources”表单,其中finally会自动处理,那就更简单/更可靠了。


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

  • try块从最后掉落时,
  • 当它抛出异常时...无论是否在此级别捕获异常,或
  • 执行returncontinuebreak

实际上,finally块未执行的情况是try块调用System.exit()或JVM崩溃。 (或者,如果它进入无限循环......)

答案 1 :(得分:3)

如果您遇到意外的异常(未捕获和处理)。

答案 2 :(得分:3)

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

因此,如果您在finally块之后放置清理代码,则在异常时不会调用它。

答案 3 :(得分:1)

如果发生Exception,即执行try块,那么,请放心,finally块也将被执行。它只是一个安全选项,而不是假设该方法的其余部分将被执行,这是不可靠的假设。

答案 4 :(得分:1)

  

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

因为代码的清理与你的try做了一个尝试打开资源等的操作有关,而且逻辑上它应该是final子句的一部分,因为它是最后一个与您try相关的操作 例如,由于在返回之前必须进行一些处理,因此关闭文件或连接100行是没有意义的 你得到了结果。没有例外,释放资源。最好在finally中执行此操作,以便您的代码更清晰,因为它始终执行

答案 5 :(得分:0)

  

在finally块运行之后,该方法的其余部分继续

只有在没有捕获异常的情况下才会这样。如果try块内发生异常,则执行catch块(如果有一个用于此异常),将执行finally块,然后如果catch块进一步抛出异常,则将控制权交给方法的调用者,没有在此方法中运行任何进一步的代码。

编辑:澄清捕获当然必须返回,而不仅仅是吃异常。

答案 6 :(得分:0)

  

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

您可以这样做,但您必须通过传递需要关闭的对象引用(非Java资源)在finally块中再次调用此函数。因为如果这个函数没有最终阻塞,并且如果发生任何异常,那么将跳过整个方法而不关闭非java资源。

你也可以使用java7功能 - > try-catch with resources。非Java资源将自动关闭。您不需要使用finally块。

答案 7 :(得分:0)

这里可能存在轻微的误解(或者这是我自己误解的错误)。无论方法是否在异常条件下退出,都运行finally块,例如

 try {
      throw new Exception();
 }
 finally {
      // Block of code will be called before the method exits as exception is thrown
 }

请注意,此规则存在(非常)例外情况,例如:

 try {
      System.exit(-1);
 }
 finally {
      // Block of code will be called before the method exits as exception is thrown
 }

这是一个(非常危险的)情况,程序将在没有执行finally块的情况下退出

答案 8 :(得分:0)

最终阻止对人们和编译器一样好。

不仅要注意编译器,还要注意阅读代码的人。 如果清理部分在finally块中,则编辑代码会很容易。

答案 9 :(得分:0)

最后Block将100%肯定执行try / catch将完全执行或不执行。

因此,如果您想释放系统资源,请在finally块中编写代码。 并返回方法的陈述。