我很困惑为什么我需要将清理代码放在finally
块中关闭流。
我已经读过finally
块中的代码无论如何都会运行(是否存在异常);并且在finally
块运行后,该方法的其余部分继续。
我的问题是:如果方法的其余部分必须继续,那么为什么我不在函数中的try / catch块之后放入清理代码?
答案 0 :(得分:10)
我的问题是;如果方法的其余部分必须继续,那么为什么我不在函数中的try / catch块之后放置清理代码。
基本上,像这样:
InputStream is = ...
try {
// use stream
} catch (IOException ex) {
// report / recover
}
is.close();
但如果// use stream
部分抛出不同的(例如未经检查的)异常,会发生什么?还是// report / recover
代码?在任何一种情况下,close()
调用都不会发生。 (如果这些块中有break
或return
语句会怎么样?)
理论上可以这样实现。问题是确保代码始终(即始终)运行。如果没有抓住一大堆你不应该抓住的例外情况,很难做到这一点......如果你抓到了,就无法妥善处理。
总而言之,finally
是更好的解决方案。
如果您可以使用新的Java 7“try with resources”表单,其中finally
会自动处理,那就更简单/更可靠了。
我想补充一点,你对finally
子句执行时的描述有点不准确。实际上,无论try块如何终止,都会执行finally
块,包括:
try
块从最后掉落时,return
,continue
或break
。实际上,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块中编写代码。 并返回方法的陈述。