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

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

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

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

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

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

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

基本上,像这样:

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

但是如果// use stream部分抛出一个不同的(例如未经检查的)exception会发生什么? 或者// report / recover代码? 无论哪种情况,都不会发生close()调用。 (如果这些块中有breakreturn语句怎么办?)

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

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

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

如果您可以使用新的Java 7“尝试使用资源”forms,其中finally将自动处理,它甚至更简单/更可靠。


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

  • try块从最后掉落时,
  • 当它抛出一个exception时……无论exception是否在这个级别被捕获,或者
  • 当它执行returncontinuebreak

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

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

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

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

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

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

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

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

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

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

您还可以使用java7function – > try-catch with resources 。 非Java资源将自动关闭。 您不需要使用finally块。

也许这里有一点误会(或者这是我误解的)。 无论方法是否在exception条件下退出,都运行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块的情况下退出。

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

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

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

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