Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the circumstances under which a finally {} block will NOT execute?

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:

  • 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?

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.

like image 225
asteri Avatar asked Sep 14 '12 19:09

asteri


People also ask

Does finally {} block always run?

A finally block always executes, regardless of whether an exception is thrown.

In which scenario finally block is not executed in Java?

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.

What can prevent execution of a code in a finally block?

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.

When finally block is not executed in Python?

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.


1 Answers

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()!

like image 198
Peter Lawrey Avatar answered Sep 30 '22 13:09

Peter Lawrey