考虑到这段代码,我能绝对确定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");
}
当前回答
如果不处理异常,在终止程序之前,JVM将执行finally块。仅当程序的正常执行因以下原因而失败时,才会执行程序。。
通过导致导致进程中止的致命错误。由于内存损坏,程序终止。通过调用System.exit()如果程序进入无限循环。
其他回答
我尝试了上面的示例,但稍作修改-
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。
试用间苯二酚示例
static class IamAutoCloseable implements AutoCloseable {
private final String name;
IamAutoCloseable(String name) {
this.name = name;
}
public void close() {
System.out.println(name);
}
}
@Test
public void withResourceFinally() {
try (IamAutoCloseable closeable1 = new IamAutoCloseable("closeable1");
IamAutoCloseable closeable2 = new IamAutoCloseable("closeable2")) {
System.out.println("try");
} finally {
System.out.println("finally");
}
}
测试输出:
try
closeable2
closeable1
finally
不总是这样
Java语言规范描述了try-catch finally和try-catch块在14.20.2在任何地方,它都不会指定始终执行finally块。但对于try-catch-finally和try-finally块完成的所有情况,它确实指定在完成之前必须执行finally。
try {
CODE inside the try block
}
finally {
FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).
JLS不保证在CODE之后执行FIN。JLS保证,如果执行CODE和NEXT,则FIN将始终在CODE之后和NEXT之前执行。
为什么JLS不能保证finally块总是在try块之后执行?因为这是不可能的。在完成try块之后但在执行finally块之前,JVM不太可能被中止(终止、崩溃、断电)。JLS无法避免这种情况。
因此,任何软件的正常行为都取决于最终块,总是在其尝试块完成后执行。
try块中的返回指令与此问题无关。如果执行在try-catch finally之后到达代码,则可以保证finally块之前已经执行过,无论是否在try块内有返回指令。
除非由于JVM崩溃或调用System.exit(0)而导致程序异常终止,否则finally块将始终执行。
除此之外,finally块中返回的任何值都将覆盖finally块执行之前返回的值,因此在使用try finally时,请注意检查所有退出点。
是的,写在这里
如果在执行try或catch代码时JVM退出,那么finally块可能不会执行。同样,如果执行try或catch代码的线程被中断或终止,那么即使整个应用程序继续运行,finally块也可能不会执行。