最后块是否真的需要清理代码(如关闭流)?
我很困惑为什么我需要将清理代码放在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()
调用。 (如果这些块中有break
或return
语句怎么办?)
理论上可以这种方式实现它。 问题是确保代码始终(即始终)运行。 如果没有抓住一堆你不应该抓住的例外情况,那么很难做到这一点……如果你抓住它就无法妥善处理。
总而言之, finally
是更好的解决方案。
- 它比你正确处理这种情况需要做的卷积更简单,并且
- 它比典型的半心半意的尝试更可靠。
如果您可以使用新的Java 7“尝试使用资源”forms,其中finally
将自动处理,它甚至更简单/更可靠。
我想补充一点,你对finally
子句执行时的描述有点不准确。 实际上,无论try块如何终止,都会执行finally
块,包括:
- 当
try
块从最后掉落时, - 当它抛出一个exception时……无论exception是否在这个级别被捕获,或者
- 当它执行
return
,continue
或break
。
事实上, 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块中编写代码。 并返回方法的语句。
- 如何在Spring中拦截RequestRejectedException?
- 无限循环当在try-catch块中捕获InputMidmatchException时
- Java中是否有未处理的exception处理程序?
- 为什么Java编译器允许在throws部分中列出exception,该方法无法抛出exception
- 最后在exception处理中
- 如何使用hasNextInt()来捕获exception? 我需要Int,但如果输入是字符,那就很糟糕
- 当序列化策略更改时,GWT客户端不会收到IncompatibleRemoteServiceException
- java.net.BindException:已在使用的地址:JVM_Bind :80
- JVM如何保证finally块的执行?