Question

Considering this code, can I be absolutely sure that the finally block always executes, no matter what something() is?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}
Was it helpful?

Solution

Yes, finally will be called after the execution of the try or catch code blocks.

The only times finally won't be called are:

  1. If you invoke System.exit()
  2. If the JVM crashes first
  3. If the JVM reaches an infinite loop (or some other non-interruptable, non-terminating statement) in the try or catch block
  4. If the OS forcibly terminates the JVM process; e.g., kill -9 <pid> on UNIX
  5. If the host system dies; e.g., power failure, hardware error, OS panic, et cetera
  6. If the finally block is going to be executed by a daemon thread and all other non-daemon threads exit before finally is called

OTHER TIPS

Example code:

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int test() {
    try {
        return 0;
    }
    finally {
        System.out.println("finally trumps return.");
    }
}

Output:

finally trumps return. 
0

Also, although it's bad practice, if there is a return statement within the finally block, it will trump any other return from the regular block. That is, the following block would return false:

try { return true; } finally { return false; }

Same thing with throwing exceptions from the finally block.

Here's the official words from the Java Language Specification.

14.20.2. Execution of try-finally and try-catch-finally

A try statement with a finally block is executed by first executing the try block. Then there is a choice:

  • If execution of the try block completes normally, [...]
  • If execution of the try block completes abruptly because of a throw of a value V, [...]
  • If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
    • If the finally block completes normally, then the try statement completes abruptly for reason R.
    • If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

The specification for return actually makes this explicit:

JLS 14.17 The return Statement

ReturnStatement:
     return Expression(opt) ;

A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it.

A return statement with an Expression attempts to transfer control to the invoker of the method that contains it; the value of the Expression becomes the value of the method invocation.

The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements within the method or constructor whose try blocks contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.

In addition to the other responses, it is important to point out that 'finally' has the right to override any exception/returned value by the try..catch block. For example, the following code returns 12:

public static int getMonthsInYear() {
    try {
        return 10;
    }
    finally {
        return 12;
    }
}

Similarly, the following method does not throw an exception:

public static int getMonthsInYear() {
    try {
        throw new RuntimeException();
    }
    finally {
        return 12;
    }
}

While the following method does throw it:

public static int getMonthsInYear() {
    try {
        return 12;          
    }
    finally {
        throw new RuntimeException();
    }
}

I tried the above example with slight modification-

public static void main(final String[] args) {
    System.out.println(test());
}

public static int test() {
    int i = 0;
    try {
        i = 2;
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
    }
}

The above code outputs:

finally trumps return.
2

This is because when return i; is executed i has a value 2. After this the finally block is executed where 12 is assigned to i and then System.out out is executed.

After executing the finally block the try block returns 2, rather than returning 12, because this return statement is not executed again.

If you will debug this code in Eclipse then you'll get a feeling that after executing System.out of finally block the return statement of try block is executed again. But this is not the case. It simply returns the value 2.

Here's an elaboration of Kevin's answer. It's important to know that the expression to be returned is evaluated before finally, even if it is returned after.

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int printX() {
    System.out.println("X");
    return 0;
}

public static int test() {
    try {
        return printX();
    }
    finally {
        System.out.println("finally trumps return... sort of");
    }
}

Output:

X
finally trumps return... sort of
0

That is the whole idea of a finally block. It lets you make sure you do cleanups that might otherwise be skipped because you return, among other things, of course.

Finally gets called regardless of what happens in the try block (unless you call System.exit(int) or the Java Virtual Machine kicks out for some other reason).

A logical way to think about this is:

  1. Code placed in a finally block must be executed whatever occurs within the try block
  2. So if code in the try block tries to return a value or throw an exception the item is placed 'on the shelf' till the finally block can execute
  3. Because code in the finally block has (by definition) a high priority it can return or throw whatever it likes. In which case anything left 'on the shelf' is discarded.
  4. The only exception to this is if the VM shuts down completely during the try block e.g. by 'System.exit'

Also a return in finally will throw away any exception. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html

finally is always executed unless there is abnormal program termination (like calling System.exit(0)..). so, your sysout will get printed

The finally block is always executed unless there is abnormal program termination, either resulting from a JVM crash or from a call to System.exit(0).

On top of that, any value returned from within the finally block will override the value returned prior to execution of the finally block, so be careful of checking all exit points when using try finally.

No, not always one exception case is// System.exit(0); before the finally block prevents finally to be executed.

  class A {
    public static void main(String args[]){
        DataInputStream cin = new DataInputStream(System.in);
        try{
            int i=Integer.parseInt(cin.readLine());
        }catch(ArithmeticException e){
        }catch(Exception e){
           System.exit(0);//Program terminates before executing finally block
        }finally{
            System.out.println("Won't be executed");
            System.out.println("No error");
        }
    }
}

Finally is always run that's the whole point, just because it appears in the code after the return doesn't mean that that's how it's implemented. The Java runtime has the responsibility to run this code when exiting the try block.

For example if you have the following:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("done");
    }
}

The runtime will generate something like this:

int foo() {
    int ret = 42;
    System.out.println("done");
    return 42;
}

If an uncaught exception is thrown the finally block will run and the exception will continue propagating.

This is because you assigned the value of i as 12, but did not return the value of i to the function. The correct code is as follows:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}

Because a finally block will always be called unless you call System.exit() (or the thread crashes).

Answer is simple YES.

INPUT:

try{
    int divideByZeroException = 5 / 0;
} catch (Exception e){
    System.out.println("catch");
    return;    // also tried with break; in switch-case, got same output
} finally {
    System.out.println("finally");
}

OUTPUT:

catch
finally

Yes it will get called. That's the whole point of having a finally keyword. If jumping out of the try/catch block could just skip the finally block it was the same as putting the System.out.println outside the try/catch.

Concisely, in the official Java Documentation (Click here), it is written that -

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.

Yes, finally block is always execute. Most of developer use this block the closing the database connection, resultset object, statement object and also uses into the java hibernate to rollback the transaction.

Yes, it will. No matter what happens in your try or catch block unless otherwise System.exit() called or JVM crashed. if there is any return statement in the block(s),finally will be executed prior to that return statement.

Yes It will. Only case it will not is JVM exits or crashes

Consider the following program:

public class SomeTest {

    private static StringBuilder sb = new StringBuilder();

    public static void main(String args[]) {

        System.out.println(someString());
        System.out.println("---AGAIN---");
        System.out.println(someString());
        System.out.println("---PRINT THE RESULT---");
        System.out.println(sb.toString());
    }

    private static String someString() {

        try {
            sb.append("-abc-");
            return sb.toString();

        } finally {
            sb.append("xyz");
        }
    }
}

As of Java 1.8.162, the above code block gives the following output:

-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz

this means that using finally to free up objects is a good practice like the following code:

private static String someString() {

    StringBuilder sb = new StringBuilder();

    try {
        sb.append("abc");
        return sb.toString();

    } finally {
        sb = null; // Just an example, but you can close streams or DB connections this way.
    }
}

That's actually true in any language...finally will always execute before a return statement, no matter where that return is in the method body. If that wasn't the case, the finally block wouldn't have much meaning.

finally will execute and that is for sure.

finally will not execute in below cases:

case 1 :

When you are executing System.exit().

case 2 :

When your JVM / Thread crashes.

case 3 :

When your execution is stopped in between manually.

If you don't handle exception, before terminating the program, JVM executes finally block. It will not executed only if normal execution of program will fail mean's termination of program due to these following reasons..

  1. By causing a fatal error that causes the process to abort.

  2. Termination of program due to memory corrupt.

  3. By calling System.exit()

  4. If program goes into infinity loop.

Yes, because no control statement can prevent finally from being executed.

Here is a reference example, where all code blocks will be executed:

| x | Current result | Code 
|---|----------------|------ - - -
|   |                |     
|   |                | public static int finallyTest() {
| 3 |                |     int x = 3;
|   |                |     try {
|   |                |        try {
| 4 |                |             x++;
| 4 | return 4       |             return x;
|   |                |         } finally {
| 3 |                |             x--;
| 3 | throw          |             throw new RuntimeException("Ahh!");
|   |                |         }
|   |                |     } catch (RuntimeException e) {
| 4 | return 4       |         return ++x;
|   |                |     } finally {
| 3 |                |         x--;
|   |                |     }
|   |                | }
|   |                |
|---|----------------|------ - - -
|   | Result: 4      |

In the variant below, return x; will be skipped. Result is still 4:

public static int finallyTest() {
    int x = 3;
    try {
        try {
            x++;
            if (true) throw new RuntimeException("Ahh!");
            return x; // skipped
        } finally {
            x--;
        }
    } catch (RuntimeException e) {
        return ++x;
    } finally {
        x--;
    }
}

References, of course, track their status. This example returns a reference with value = 4:

static class IntRef { public int value; }
public static IntRef finallyTest() {
    IntRef x = new IntRef();
    x.value = 3;
    try {
        return x;
    } finally {
        x.value++; // will be tracked even after return
    }
}

try- catch- finally are the key words for using exception handling case.
As normal explanotory

try {
     //code statements
     //exception thrown here
     //lines not reached if exception thrown
} catch (Exception e) {
    //lines reached only when exception is thrown
} finally {
    // always executed when the try block is exited
    //independent of an exception thrown or not
}

The finally block prevent executing...

  • When you called System.exit(0);
  • If JVM exits.
  • Errors in the JVM

Adding to @vibhash's answer as no other answer explains what happens in the case of a mutable object like the one below.

public static void main(String[] args) {
    System.out.println(test().toString());
}

public static StringBuffer test() {
    StringBuffer s = new StringBuffer();
    try {
        s.append("sb");
        return s;
    } finally {
        s.append("updated ");
    }
}

Will output

sbupdated 

I tried this, It is single threaded.

class Test {
    public static void main(String args[]) throws Exception {
       Object obj = new Object();
       try {
            synchronized (obj) {
            obj.wait();
            System.out.println("after wait()");
           }
       } catch (Exception e) {
       } finally {
           System.out.println("finally");
       }
   }
}

The main thread will be on wait state forever, hence finally will never be called,

so console output will not print string: after wait() or finally

Agreed with @Stephen C, the above example is one of the 3rd case mention here:

Adding some more such infinite loop possibilities in following code:

// import java.util.concurrent.Semaphore;
class Test {
    public static void main(String[] args) {
        try {
            // Thread.sleep(Long.MAX_VALUE);
            // Thread.currentThread().join();
            // new Semaphore(0).acquire();
            // while (true){}
            System.out.println("after sleep join semaphore exit infinite while loop");
        } catch (Exception e) {
        } finally {
            System.out.println("finally");
        }
    }
}

Case 2: If the JVM crashes first

import sun.misc.Unsafe;
import java.lang.reflect.Field;
class Test {
    public static void main(String args[]) {
        try {
            unsafeMethod();
//            Runtime.getRuntime().halt(123);
            System.out.println("After Jvm Crash!");
        } catch (Exception e) {
        } finally {
            System.out.println("finally");
        }
    }

    private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        Unsafe unsafe = (Unsafe) f.get(null);
        unsafe.putAddress(0, 0);
    }
}

Ref: How do you crash a JVM?

Case 6: If finally block is going to be executed by daemon thread and all other non-daemon threads exit before finally is called.

class Test {
    public static void main(String args[]) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    printThreads("Daemon Thread printing");
                    // just to ensure this thread will live longer than main thread
                    Thread.sleep(10000);
                } catch (Exception e) {
                } finally {
                    System.out.println("finally");
                }
            }
        };
        Thread daemonThread = new Thread(runnable);
        daemonThread.setDaemon(Boolean.TRUE);
        daemonThread.setName("My Daemon Thread");
        daemonThread.start();
        printThreads("main Thread Printing");
    }

    private static synchronized void printThreads(String str) {
        System.out.println(str);
        int threadCount = 0;
        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
        for (Thread t : threadSet) {
            if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
                System.out.println("Thread :" + t + ":" + "state:" + t.getState());
                ++threadCount;
            }
        }
        System.out.println("Thread count started by Main thread:" + threadCount);
        System.out.println("-------------------------------------------------");
    }
}

output: This does not print "finally" which implies "Finally block" in "daemon thread" did not execute

main Thread Printing  
Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED  
Thread :Thread[main,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE   
Thread count started by Main thread:3  
-------------------------------------------------  
Daemon Thread printing  
Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE  
Thread count started by Main thread:2  
-------------------------------------------------  

Process finished with exit code 0
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top