Does a finally block always run?

Viewed 83603

Is there any condition where finally might not run in java? Thanks.

12 Answers

from the Sun Tutorials

Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

I don't know of any other ways the finally block wouldn't execute...

System.exit shuts down the Virtual Machine.

Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.

This method calls the exit method in class Runtime. This method never returns normally.

    try {
        System.out.println("hello");
        System.exit(0);
    }
    finally {
        System.out.println("bye");
    } // try-finally

"bye" does not print out in above code.

Just to expand on what others have said, anything that does not cause something like the JVM exiting will incur the finally block. So the following method:

public static int Stupid() {
  try {
    return 0;
  }
  finally {
    return 1;
  }
}

will strangely both compile and return 1.

Related to System.exit, there are also certain types of catastrophic failure where a finally block may not execute. If the JVM runs out of memory entirely, it may just exit without catch or finally happening.

Specifically, I remember a project where we foolishly tried to use

catch (OutOfMemoryError oome) {
    // do stuff
}

This didn't work because the JVM had no memory left for executing the catch block.

try { for (;;); } finally { System.err.println("?"); }

In that case the finally will not execute (unless the deprecated Thread.stop is called, or an equivalent, say, through a tools interface).

There are two ways to stop finally block code execution:
1. Use System.exit();
2. If somehow execution control don't reach to try block.
See:

public class Main
{
  public static void main (String[]args)
  {
    if(true){
        System.out.println("will exceute");
    }else{
        try{
            System.out.println("result = "+5/0);
        }catch(ArithmeticException e){
          System.out.println("will not exceute");
        }finally{
          System.out.println("will not exceute");  
        }
    }
  }
}
Related