ast*_*eri 31 java jvm try-catch try-catch-finally
在Java try{} ... catch{} ... finally{}块中,finally{}无论try/catch中发生什么,通常都认为其中的代码是"保证"运行的.但是,我知道至少有两种情况不会执行:
System.exit(0)被召唤; 要么,printStackTrace()退出)是否有任何其他程序行为会阻止finally{}块中的代码执行?代码在什么具体条件下执行?
编辑:正如NullUserException指出的那样,第二种情况实际上并非如此.我认为这是因为标准错误中的文本在标准输出之后打印出来,防止文本在没有向上滚动的情况下被看到.:) 道歉.
Pet*_*rey 33
如果你调用System.exit()程序立即退出而不finally被调用.
JVM崩溃,例如Segmentation Fault,也会阻止最终被调用.即JVM此时立即停止并生成崩溃报告.
无限循环也会阻止最终被调用.
抛出Throwable时始终会调用finally块.即使你调用Thread.stop()ThreadDeath也会触发一个在目标线程中抛出的东西.这可以被捕获(它是一个Error)并且将调用finally块.
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();
}
Run Code Online (Sandbox Code Playgroud)
版画
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
Run Code Online (Sandbox Code Playgroud)
注意:在每种情况下,线程都保持运行,即使在SO,OOME,Interrupted和Thread.stop()之后!