考虑到这段代码,我能绝对确定finally块总是执行的吗,不管something()是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
考虑到这段代码,我能绝对确定finally块总是执行的吗,不管something()是什么?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
当前回答
即使在try块中放入return语句,也始终执行finally块。finally块将在return语句之前执行。
其他回答
这是Java语言规范中的官方词汇。
14.20.2.执行try finally和try catch finally
带有finally块的try语句通过首先执行try块来执行。然后有一个选择:如果try块的执行正常完成,[…]如果try块的执行因抛出值V而突然完成,[…]如果由于任何其他原因R,try块的执行突然完成,则执行finally块。然后有一个选择:如果finally块正常完成,则try语句由于原因R而突然完成。如果finally块因原因S而突然完成,则try语句因原因S突然完成(并且原因R被丢弃)。
返回的规范实际上明确了这一点:
JLS 14.17退货声明
退货声明:返回表达式(opt);没有表达式的return语句试图将控制传递给包含它的方法或构造函数的调用者。带有表达式的return语句试图将控制权传递给包含它的方法的调用者;表达式的值变为方法调用的值。前面的描述说的是“试图传递控制”而不仅仅是“传递控制”,因为如果在方法或构造函数中有任何try语句,其try块包含return语句,那么在将控制传递给方法或构造函数的调用程序之前,这些try语句的任何finally子句都将按从内到外的顺序执行。finally子句的突然完成可能会中断由return语句发起的控制权转移。
如果不处理异常,在终止程序之前,JVM将执行finally块。仅当程序的正常执行因以下原因而失败时,才会执行程序。。
通过导致导致进程中止的致命错误。由于内存损坏,程序终止。通过调用System.exit()如果程序进入无限循环。
除非由于JVM崩溃或调用System.exit(0)而导致程序异常终止,否则finally块将始终执行。
除此之外,finally块中返回的任何值都将覆盖finally块执行之前返回的值,因此在使用try finally时,请注意检查所有退出点。
考虑以下程序:
public class SomeTest {
private static StringBuilder sb = new StringBuilder();
public static void main(String args[]) {
System.out.println(someString());
System.out.println("---AGAIN---");
System.out.println(someString());
System.out.println("---PRINT THE RESULT---");
System.out.println(sb.toString());
}
private static String someString() {
try {
sb.append("-abc-");
return sb.toString();
} finally {
sb.append("xyz");
}
}
}
从Java 1.8.162开始,上述代码块提供以下输出:
-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz
这意味着使用finally释放对象是一种很好的做法,如以下代码所示:
private static String someString() {
StringBuilder sb = new StringBuilder();
try {
sb.append("abc");
return sb.toString();
} finally {
sb = null; // Just an example, but you can close streams or DB connections this way.
}
}
与以下代码相同:
static int f() {
while (true) {
try {
return 1;
} finally {
break;
}
}
return 2;
}
f将返回2!