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)
is called; or,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?
EDIT: 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.
A finally block always executes, regardless of whether an exception is thrown.
Condition where finally block is not executed in Java When the System. exit() method is called in the try block before the execution of finally block, finally block will not be executed.
The finally block follows a try block or a catch block. A finally block of code always executes, irrespective of occurrence of an Exception. You cannot skip the execution of the final block. Still if you want to do it forcefully when an exception occurred, the only way is to call the System.
The finally block always executes after normal termination of try block or after try block terminates due to some exception. finally block is always executed after leaving the try statement. In case if some exception was not handled by except block, it is re-raised after execution of finally block.
If you call System.exit()
the program exits immediately without finally
being called.
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.
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(); }
prints
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
Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With