考虑到这段代码,我能绝对确定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");
}
当前回答
此外,finally的返回将丢弃任何异常。http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
其他回答
我很晚才回答,但我很惊讶没有人提到Java调试器选项来删除堆栈帧。我是IntelliJ中此功能的重度用户。(我确信Eclipse和NetBeans支持相同的功能。)
如果我从后面跟着finally块的try或catch块中删除堆栈帧,IDE将提示我:“我要执行finally块吗?”显然,这是一个人工运行时环境——调试器!
为了回答您的问题,我想说,只有在连接调试器时忽略,并且(就像其他人所说的)method something()不(a)通过JNI调用Java方法System.exit(int)或(b)C函数exit(int/abort(),或(C)对自身执行类似于调用kill-9$PID(!)的疯狂操作时,才能保证它运行。
即使在try块中放入return语句,也始终执行finally块。finally块将在return语句之前执行。
我尝试了上面的示例,但稍作修改-
public static void main(final String[] args) {
System.out.println(test());
}
public static int test() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
}
}
上述代码输出:
最终战胜了回报。2.
这是因为当返回i;i的值为2。在此之后,执行finally块,其中12被分配给i,然后执行System.out-out。
在执行finally块之后,try块返回2,而不是返回12,因为该返回语句不会再次执行。
如果您将在Eclipse中调试此代码,那么您会感觉到在执行System.out of finally块之后,try块的返回语句将再次执行。但事实并非如此。它只返回值2。
除了最后替换try块中的返回之外,异常也是如此。引发异常的finally块将替换try块中引发的返回或异常。
考虑这一点的逻辑方法是:
放置在finally块中的代码必须在try块中执行因此,如果try块中的代码试图返回一个值或抛出一个异常,则该项将被“搁置”,直到finally块可以执行因为finally块中的代码(根据定义)具有高优先级,所以它可以返回或抛出任何它喜欢的东西。在这种情况下,“搁在架子上”的任何东西都会被丢弃。唯一的例外是,如果VM在try块期间完全关闭,例如通过“System.exit”