呼び出すとSystem.exit()
、プログラムは呼び出されずにすぐに終了しますfinally
。
セグメンテーション違反などのJVMクラッシュも、最終的に呼び出されるのを防ぎます。つまり、JVMはこの時点ですぐに停止し、クラッシュレポートを生成します。
無限ループは、最終的に呼び出されることも防ぎます。
Throwableがスローされると、finallyブロックが常に呼び出されます。ThreadDeath
ターゲットスレッドでスローされるようにトリガーするThread.stop()を呼び出した場合でも。これをキャッチすることができ(これは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();
}
プリント
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
注:いずれの場合も、SO、OOME、Interrupted、Thread.stop()の後でも、スレッドは実行を続けました。