Try...[Catch]...Finally
块中Finally
块的意义是什么?
这不是代码吗
Resource r;
try{
r = new Resource();
r.methodThatThrowsException();
} catch (Exception e) {
e.printStackTrace()
} finally {
r.close()
}
相当于
Resource r;
try{
r = new Resource();
r.methodThatThrowsException();
} catch (Exception e) {
e.printStackTrace()
}
r.close()
?如果它们具有相同的范围,我会理解,但是无论如何我都必须在try块之外定义Resource r
才能在finally 块中使用它,这意味着我认为使用finally 块没有任何优势。
我错过了什么吗?有没有我没有想到的某种情况需要 Final 块?
在这种情况下,它们是等效的,因为 (a( 代码捕获任何异常,包括引发的运行时异常,以及 (b( catch 块不会重新引发异常,因此执行继续。
finally
块通常用于确保在 (a( 或 (b( 不成立的情况下释放资源。在较新的 Java 实现中,应尽可能改用try-with-resources
。
这两个代码片段是不同的:如果异常处理块以另一个异常结尾,则第二个代码段不会关闭。
下面是一个插图:
public static void one() throws Exception {
try {
System.out.println("One");
throw new Exception();
} catch (Exception e) {
System.out.println("Catch one");
if (2 != 3) throw new Exception(); // "if" silences compiler's check
} finally {
System.out.println("Finally one");
}
}
public static void two() throws Exception {
try {
System.out.println("Two");
throw new Exception();
} catch (Exception e) {
System.out.println("Catch two");
if (2 != 3) throw new Exception(); // "if" silences compiler's check
}
System.out.println("After two");
}
对one()
的调用打印Finally one
,而After two
永远不会打印(演示 1(。
当您捕获特定异常时,finally
块变得更加重要(盲目捕获Exception
几乎总是一个坏主意(,因为try
块可能会通过抛出您未捕获的异常来绕过清理代码。这是另一个插图:
public static void error() throws Exception {
try {
System.out.println("Try");
throw new Error();
} catch (Exception e) {
System.out.println("Catch");
throw new Exception();
} finally {
System.out.println("Finally");
}
}
此代码打印Try
和Finally
,中间没有Catch
,因为Error
没有被捕获在catch
块中(演示 2(。
不言而喻,如果你将程序的人类读者放在finally
块中,它将更容易找到你的清理代码。
不,它不等同。在第一个代码段中,将始终调用r.close()
,而在第二个代码段中,可能不会调用r.close()
:
- 当 try 块引发
Error
时(使用断言而断言失败时会发生什么情况( - 当异常处理程序引发另一个异常时
为了确保始终释放资源close()
应从finally
块调用该方法。