finally {}块不会执行的情况是什么? [英] What are the circumstances under which a finally {} block will NOT execute?
问题描述
在Java 中尝试{} ... catch {} ... finally {}
阻止,中的代码最终{} 无论try / catch中发生什么,code>通常被认为是保证运行。但是,我知道至少有两种情况,不执行:
In a Java try{} ... catch{} ... finally{}
block, code within the finally{}
is generally considered "guaranteed" to run regardless of what occurs in the try/catch. However, I know of at least two circumstances under which it will not execute:
- 如果
调用System.exit(0)
;或者, - 如果异常被抛出到JVM并且出现默认行为(即
printStackTrace()
并且退出)
- If
System.exit(0)
is called; or, - if an Exception is thrown all the way up to the JVM and the default behavior occurs (i.e.,
printStackTrace()
and exit)
是否有任何其他程序行为会阻止中的代码最终{}
阻止执行?代码在什么具体条件下执行?
Are there any other program behaviors that will prevent the code in a finally{}
block from executing? Under what specific conditions will the code execute or not?
编辑:由于NullUserException指出,第二种情况实际上并非如此。我认为这是因为标准错误中的文本在标准输出之后打印出来,防止文本在没有向上滚动的情况下被看到。 :)道歉。
As NullUserException pointed out, the second case is actually not true. I thought it was because the text in standard error printed after that in standard out, preventing the text from being seen without scrolling up. :) Apologies.
推荐答案
如果你打电话给 System.exit()
没有最后
被调用。
If you call System.exit()
the program exits immediately without finally
being called.
JVM崩溃例如分段错误,也会阻止最终被调用。即JVM此时立即停止并生成崩溃报告。
A JVM Crash e.g. Segmentation Fault, will also prevent finally being called. i.e. the JVM stops immediately at this point and produces a crash report.
无限循环也会阻止最终被调用。
An infinite loop would also prevent a finally being called.
抛出Throwable时总是调用finally块。即使你调用Thread.stop()来触发 <要在目标线程中抛出code> ThreadDeath 。这可以被捕获(这是一个 错误
)将调用finally块。
The finally block is always called when a Throwable is thrown. Even if you call Thread.stop() which triggers a ThreadDeath
to be thrown in the target thread. This can be caught (it's an Error
) and the finally block will be called.
public static void main(String[] args) {
testOutOfMemoryError();
testThreadInterrupted();
testThreadStop();
testStackOverflow();
}
private static void testThreadStop() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
@Override
public void run() {
thread.stop();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testThreadInterrupted() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
@Override
public void run() {
thread.interrupt();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testOutOfMemoryError() {
try {
try {
List<byte[]> bytes = new ArrayList<byte[]>();
while(true)
bytes.add(new byte[8*1024*1024]);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow() {
try {
try {
testStackOverflow0();
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow0() {
testStackOverflow0();
}
打印
finally called after java.lang.OutOfMemoryError: Java heap space
finally called after java.lang.InterruptedException: sleep interrupted
finally called after java.lang.ThreadDeath
finally called after java.lang.StackOverflowError
注意:每个case线程保持运行,即使在SO,OOME,Interrupted和Thread.stop()之后!
Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!
这篇关于finally {}块不会执行的情况是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!