By jonny five


2008-09-15 17:43:54 8 Comments

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");
}

30 comments

@Sam 2018-04-30 08:36:45

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.
    }
}

@user7294900 2018-09-05 06:38:32

Shouldn't it be sb.setLength(0) in finally?

@Sam 2018-09-05 17:16:56

sb.setLength(0) will just empty the data in the StringBuffer. So, sb = null will disassociate the object from the reference.

@fresko 2019-02-13 10:22:58

Shouldn't "xyz" be printed twice in the output? Since the function was called twice, why "finally" was only once?

@Sam 2019-02-13 15:21:13

@fresko : finallly is definitely called twice but when it comes to the output in the console it will only show once because of the return statement. You can run the program and see the output, and after that add another statement System.out.println(sb.toString());

@Roc Boronat 2019-02-15 23:58:34

This isn't a good practice. That finally block with sb = null; just adds unneeded code. I understand that you mean that a finally block is a good place to free resources like a database connection or something like that, but have in mind that your example could confuse newcomers.

@fresko 2019-02-19 13:08:37

@Samim Thanks, I added the lines System.out.println("---AGAIN2---"); System.out.println(sb); and it's more clear now. As it was, the output was against your thesis :p I also added to your answer, but the edit must be accepted by a moderator or somebody like that. Else you can add them

@Anonymous Coward 2015-12-12 14:30:53

NOT ALWAYS

The Java Language specification describes how try-catch-finally and try-catch blocks work at 14.20.2
In no place it specifies that the finally block is always executed. But for all cases in which the try-catch-finally and try-finally blocks complete it does specify that before completion finally must be executed.

try {
  CODE inside the try block
}
finally {
  FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).

The JLS does not guarantee that FIN is executed after CODE. The JLS guarantees that if CODE and NEXT are executed then FIN will always be executed after CODE and before NEXT.

Why doesn't the JLS guarantee that the finally block is always executed after the try block? Because it is impossible. It is unlikely but possible that the JVM will be aborted (kill, crash, power off) just after completing the try block but before execution of the finally block. There is nothing the JLS can do to avoid this.

Thus, any software which for their proper behaviour depends on finally blocks always being executed after their try blocks complete are bugged.

return instructions in the try block are irrelevant to this issue. If execution reaches code after the try-catch-finally it is guaranteed that the finally block will have been executed before, with or without return instructions inside the try block.

@hellzone 2020-01-27 13:24:21

finally is always executed and before returning x's (calculated) value.

System.out.println(foo());

....

int foo(){
    int x = 2;
    try{
        return x++;
    } finally{
        System.out.println(x);
    }
}

Output:

3
2

@President James K. Polk 2020-02-04 19:37:12

Nice illustrative example, +1.

@HopefullyHelpful 2016-04-28 22:11:32

finally can also be exited prematurely if an Exception is thrown inside a nested finally block. The compiler will warn you that the finally block does not complete normally or give an error that you have unreachable code. The error for unreachable code will be shown only if the throw is not behind a conditional statement or inside a loop.

try{
}finally{
   try{
   }finally{
      //if(someCondition) --> no error because of unreachable code
      throw new RunTimeException();
   }
   int a = 5;//unreachable code
}

@Loduwijk 2018-01-03 15:05:11

Just noting that this is completely normal behavior. Any/all code exits prematurely if an exception is thrown. This is no different than an exception thrown anywhere else. There is no special rule in the spec that says "exceptions cannot be used inside a finally block." Because of this, I even misunderstood your answer at first and almost gave -1, until I reread it a couple times.

@HopefullyHelpful 2018-01-03 20:56:41

Well, but how is a return different from a throw? If you return then the block should return but in a finally block, the return will be postponed and there are some weird exception for return, so it isn't clear that finally handles throw in a normal way. That is the main reason why I wrote this back then. Also throw in a try or catch block won't hinder the finally block from execution, so ofc. one might expect that when you throw in a finally block it still executes.

@Loduwijk 2018-01-04 00:24:33

"how is return different from throw?" In a few ways, none of which are relevant here. In a finally block, return is not postponed, or did you mean the return in the try-block being postponed until after finally-block executes (in which case, yes that is true)? Either way, the same holds for thrown exceptions. No matter what happens in a try, when the end of try is reached, the control passes to finally, then all the same rules apply within the finally (with any try/catch inside of finally operating as they usually would).

@Loduwijk 2018-01-04 00:29:20

I am not saying your answer is wrong or useless or anything like that. It is technically correct. I merely noted that the behavior you describe is nothing that breaks the try/finally rule which is simply "No matter what happens in try/catch, once they are done control flow will pass to the finally block" The try/finally guarantee is essentially nothing more, nothing less than that. Within any block, be it try/catch/finally or otherwise, you can within it nest other try/catch/finally blocks as you suggest. Indeed, some people are unaware of that.

@dkb 2016-03-20 16:20:42

I tried this, It is single threaded.

public static void main(String args[]) throws Exception {
    Object obj = new Object();
    try {
        synchronized (obj) {
            obj.wait();
            System.out.println("after wait()");
        }
    } catch (Exception ignored) {
    } 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;

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 ignored) {
    } finally {
        System.out.println("finally");
    }
}

Case 2: If the JVM crashes first

import sun.misc.Unsafe;
import java.lang.reflect.Field;

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.

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

@Stephen C 2017-08-20 01:27:40

See the accepted answer. This is just an edge case of "infinite loop".

@Youngrok Ko 2020-02-08 04:45:25

try-with-resoruce example

static class IamAutoCloseable implements AutoCloseable {
    private final String name;
    IamAutoCloseable(String name) {
        this.name = name;
    }
    public void close() {
        System.out.println(name);
    }
}

@Test
public void withResourceFinally() {
    try (IamAutoCloseable closeable1 = new IamAutoCloseable("closeable1");
         IamAutoCloseable closeable2 = new IamAutoCloseable("closeable2")) {
        System.out.println("try");
    } finally {
        System.out.println("finally");
    }
}

Test output:

try
closeable2
closeable1
finally

@jodonnell 2008-09-15 17:45:39

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

@Piotr Findeisen 2011-03-30 21:12:19

Actually thread.stop() does not necessarily prevent finally block from being executed.

@Andrzej Doyle 2011-09-16 11:24:48

How about we say that the finally block will be called after the try block, and before control passes to the following statements. That's consistent with the try block involving an infinite loop and hence the finally block never actually being invoked.

@dieend 2013-04-21 07:44:09

By @andrzejDoyle definition, it will return success first before going to finally block. Is that correct?

@Laurent LA RIZZA 2013-06-28 05:00:50

@dieend: It will decide that the return value will be success, executes the finally block, then gives back control to the calling function. Nothing will be returned if the finally block throws.

@ruhungry 2014-03-22 20:39:34

there is also another case, when we use nested try-catch-finally blocks

@Amrish Pandey 2014-09-11 12:07:46

also, finally block is not called in case of exception thrown by daemon thread.

@Binoy Babu 2014-12-14 03:08:06

But effective java says otherwise. informit.com/articles/article.aspx?p=1216151&seqNum=7

@Mikhail Krutov 2015-08-16 00:22:42

This is rather interesting that finally would be called when one re-throws his exception in catch() as new RuntimeException.

@avmohan 2017-01-05 10:17:01

@BinoyBabu - That's about finalizer, not finally block

@gstackoverflow 2017-03-13 08:35:17

What about Runtime#halt ?

@SusanW 2017-04-25 12:59:47

@AmrishPandey "finally block is not called in case of exception thrown by daemon thread" - really?? [Citation Needed], I think?

@Amrish Pandey 2017-06-05 16:43:48

@Amrish Pandey 2017-06-05 16:45:43

@SusanW 2017-06-05 18:21:12

@AmrishPandey The Oracle page doesn't mention daemons at all. The other (blogger) page discusses a JVM terminating, but fails to go on to show any difference vs a non-daemon thread. Reality is: on System.exit completion (incl shutdown hooks) or other termination, all threads just die where they are standing whether daemon or not: no finallys get executed either way. The blogger is incorrect where they note this as a difference ... try it yourself.

@Stephen C 2017-08-20 01:16:53

@SusanW - Correct. The reason that the daemon thread is not executing finally in that example is reason 3). It is in an infinite loop. If the loop wasn't there, then it could also fail to execute the finally for reason 1). When main method returns (and there are no non-daemon threads) it executes System.exit() ... or the equivalent. Bottom line: daemon threads are NOT an exception to the reasons given by the Answer above.

@Loduwijk 2018-01-03 15:17:19

Infinite loop is not really an exception to the "finally will be called when try block finishes" rule. Even with an infinite loop in the try block, the finally block still will execute when the try block finishes, as usual - the try block just does not finish. This is not a special case.

@Loduwijk 2018-01-03 15:20:33

"The host system dies; eg. power failure, hardware error..." is not really an exception to the finally block rule either. That's like "will return 1+1 always return 2?" "Not necessarily; a power loss can stop return 1+1 from returning 2." ... not really a part of the answer. Same thing with #4, the kill -9 example; it is sufficient for #4 and #5 both that #2 "JVM crash" is listed, which could be worded "JVM terminates abruptly" to better catch all situations.

@MC Emperor 2018-02-28 15:00:23

finally is also executed when a StackOverflowError is thrown.

@Dávid Horváth 2018-05-03 14:04:35

Java'sSystem.exit(); (like C#'s or PHP's) can be confusing for developers coming from other programming languages. In Python sys.exit() raises a (regular) SystemExit exception that can be catched. In Pascal exit is a regular control statement, and finally will be executed too.

@Mike Hill 2018-08-01 15:15:42

@MCEmperor, to piggy-back on this, although finally is executed even after a StackOverflowError, frames added to the stack within a finally block can cause an unexpected additional StackOverflowError, leading to the remaining contents of the finally block being skipped. For this reason, StackOverflowError errors can be quite dangerous. We recently ran into a difficult issue with semaphores not being released in a finally block for this very reason.

@JugsteR 2018-08-14 07:27:03

Q: Does it always? A: Yes, except... To me this means the accepted answer should be no. If there is exceptions to always, then its no. It may run most of the time. But not always. I am surprised I am one of few to react on this.

@Captain Man 2018-09-13 18:26:33

@JugsteR All of the cases when it doesn't is when something crazy happens like someone force killing the process, it entering an infinite loop, or the power going out. To me, if it behaves a certain way except in those most extreme of edge cases it's fine to say "yes always, except..." instead of "no". Actually, in the case of an infinite loop, it would still execute the finally, it's just that it never finishes what it's doing before it.

@Anonymous Coward 2018-10-24 23:38:04

If the machine is suspended. If the kernel never again gives the JVM time to execute. There are probably many more edge cases when finally is not executed. This answer gives a good and easy to understand explanation. But it would be easier and more simple to say "If the try block or try-catch block completes then the finally block is executed." The JLS uses this same kind of language.

@Mike 2019-08-07 21:53:58

Here are some conditions which can bypass a finally block:

  1. If the JVM exits while the try or catch code is being executed, then the finally block may not execute. More on sun tutorial
  2. Normal Shutdown - this occurs either when the last non-daemon thread exits OR when Runtime.exit() (some good blog). When a thread exits, the JVM performs an inventory of running threads, and if the only threads that are left are daemon threads, it initiates an orderly shutdown. When the JVM halts, any remaining daemon threads are abandoned finally blocks are not executed, stacks are not unwound the JVM just exits. Daemon threads should be used sparingly few processing activities can be safely abandoned at any time with no cleanup. In particular, it is dangerous to use daemon threads for tasks that might perform any sort of I/O. Daemon threads are best saved for "housekeeping" tasks, such as a background thread that periodically removes expired entries from an in-memory cache (source)

Last non-daemon thread exits example:

public class TestDaemon {
    private static Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    System.out.println("Is alive");
                    Thread.sleep(10);
                    // throw new RuntimeException();
                }
            } catch (Throwable t) {
                t.printStackTrace();
            } finally {
                System.out.println("This will never be executed.");
            }
        }
    };

    public static void main(String[] args) throws InterruptedException {
        Thread daemon = new Thread(runnable);
        daemon.setDaemon(true);
        daemon.start();
        Thread.sleep(100);
        // daemon.stop();
        System.out.println("Last non-daemon thread exits.");
    }
}

Output:

Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive

@Rajendra Jadi 2013-07-13 23:02:23

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");
        }
    }
}

@Franz D. 2018-09-10 18:34:23

And that's one of the reasons you really should never call System.exit()...

@Rubin Luitel 2018-05-09 21:52:07

Finally is always called at the end

when you try, it executes some code, if something happens in try, then catch will catch that exception and you could print some mssg out or throw an error, then finally block is executed.

Finally is normally used when doing cleanups, for instance, if you use a scanner in java, you should probably close the scanner as it leads to other problems such as not being able to open some file

@Sabrina 2018-04-20 23:57:32

finally block is executed always even if you put a return statement in the try block. The finally block will be executed before the return statement.

@Pradeep Kumaresan 2018-04-10 11:33:34

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 

@Sam 2018-04-30 08:28:39

As of Java 1.8.162, this is not the output.

@Poorna Senani Gamage 2018-04-16 06:01:09

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

@Danail Tsvetanov 2018-04-02 16:06:12

Yes, it is written here

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.

@Marquis of Lorne 2019-08-08 11:04:15

So when you say yes you mean no?

@Dávid Horváth 2017-12-16 15:36:36

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
    }
}

@Kevin 2008-09-15 17:59:52

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

@Alexander Pacha 2013-10-31 08:08:33

FYI: In C# the behaviour is identical apart from the fact that replacing the statement in the finally-clause with return 2; is not allowed (Compiler-Error).

@WoodenKitty 2013-12-03 23:37:57

Here is an important detail to be aware of: stackoverflow.com/a/20363941/2684342

@Harry 2014-10-26 05:20:03

IF YOU ADD CATCH BLOCK, error: missing return statement

@Zyl 2015-04-15 17:25:33

You can even add a return statement in the finally block itself, which will then override the previous return value. This also magically discards unhandled exceptions. At that point, you should consider refactoring your code.

@Trimtab 2016-06-21 04:20:19

That does not really prove that finally trumps return. The return value is printed from the caller code. Doesn't seem to prove much.

@Kevin 2016-06-21 20:02:21

@Trimtab, Yes, it's only answering the question as asked. Tristan's answer clarifies that the value to return is evaluated, the finally block is run, and then control is returned to the caller.

@Stephen C 2017-08-20 01:24:21

Sorry, but this is a demonstration not a proof. It is only a proof if you can show that this example always behaves this way on all Java platforms, AND that similar examples also always behave this way.

@Sandip Solanki 2017-11-09 09:41:41

The finally block will not be called after return in a couple of unique scenarios: if System.exit() is called first, or if the JVM crashes.

Let me try to answer your question in the easiest possible way.

Rule 1 : The finally block always run (Though there are exceptions to it. But let's stick to this for sometime.)

Rule 2 : the statements in the finally block run when control leaves a try or a catch block.The transfer of control can occur as a result of normal execution ,of execution of a break , continue, goto or a return statement, or of a propogation of an exception.

In case of a return statement specifically (since its captioned), the control has to leave the calling method , And hence calls the finally block of the corresponding try-finally structure. The return statement is executed after the finally block.

In case there's a return statement in the finally block also, it will definitely override the one pending at the try block , since its clearing the call stack.

You can refer a better explanation here : http://msdn.microsoft.com/en-us/.... the concept is mostly same in all the high level languages.

@Meet Vora 2016-08-13 07:00:38

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

@Christophe Roussy 2017-12-14 08:25:47

Answer is simple NO.

@Meet Vora 2017-12-14 09:24:49

@ChristopheRoussy How? Can you explain please?

@Christophe Roussy 2017-12-14 09:58:15

read the accepted answer, the original question is about 'Will it always execute' and it will not always. In your case it will but this does not answer the original question and may even be misleading beginners.

@Meet Vora 2017-12-15 10:41:08

then in which case it wont get execute?

@Christophe Roussy 2017-12-18 09:37:37

In all cases mentioned in other answers, see accepted answer with 1000+ upvotes.

@Vikas Suryawanshi 2017-06-08 12:41:40

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.

@Avinash Pande 2017-05-20 12:16:09

  1. Finally Block always get executed. Unless and until System.exit() statement exists there (first statement in finally block).
  2. If system.exit() is first statement then finally block won't get executed and control come out of the finally block. Whenever System.exit() statement gets in finally block till that statement finally block executed and when System.exit() appears then control force fully come out of the finally block.

@Tom 2017-05-20 12:19:36

This has been answered many times, so which new information does your answer add?

@user9189 2008-09-15 18:11:55

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.

@Utkash Bhatt 2014-12-18 06:36:56

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.

@Eyal Schneider 2010-05-13 07:11:59

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();
    }
}

@Dimitris Andreou 2010-05-13 11:54:06

It should be noted that the middle case is precisely the reason why having a return statement inside a finally block is absolutely horrible (it could hide any Throwable).

@RecursiveExceptionException 2019-02-07 18:06:06

Who doesn't want a surpressed OutOfMemoryError? ;)

@Maarten Bodewes 2019-12-22 16:02:48

I tested it and it does suppress such an error (yipes!). It also generates a warning when I compile it (yay!). And you can work around it by defining a return variable and then using return retVal after the finally block, although that of course assumes that you suppressed some other exceptions because the code would not make sense otherwise.

@WoodenKitty 2013-12-03 23:36:13

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

@Aminadav Glickshtein 2018-07-06 12:06:59

Important to know.

@Albert 2019-06-26 10:58:06

Good to know, and makes sense as well. It seems that actually returning the value of return is what comes after finally. Calculating the return value (printX() here) still comes before it.

@Pacerier 2020-05-10 01:21:29

Nope. The code above should replace System.out.println("finally trumps return... sort of"); with System.out.print("finally trumps return in try"); return 42;

@Akash Manngroliya 2016-09-13 05:36:30

Yes it will always called but in one situation it not call when you use System.exit()

try{
//risky code
}catch(Exception e){
//exception handling code
}
finally(){
//It always execute but before this block if there is any statement like System.exit(0); then this block not execute.
}

@Stephen C 2017-08-20 01:25:21

Duplicative answer

@Marquis of Lorne 2019-08-08 11:02:23

Not only 'duplicative' but self-contradictory.

@dibo 2016-07-04 14:53:53

Same with the following code:

static int f() {
    while (true) {
        try {
            return 1;
        } finally {
            break;
        }
    }
    return 2;
}

f will return 2!

@Stephen C 2017-08-20 01:25:53

Duplicative answer

@polygenelubricants 2010-05-25 06:50:16

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.

@shyam 2008-09-15 17:46:18

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

@Chris Cooper 2010-05-13 06:19:17

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).

@Gangnus 2019-05-07 18:19:17

That is an extremely weak answer. stackoverflow.com/a/65049/715269

@Wasim 2010-05-25 06:36:29

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;
    }
}

Related Questions

Sponsored Content

15 Answered Questions

[SOLVED] Why does Java have transient fields?

  • 2009-05-26 12:11:36
  • Animesh
  • 695244 View
  • 1481 Score
  • 15 Answer
  • Tags:   java field transient

6 Answered Questions

[SOLVED] Does 'finally' always execute in Python?

27 Answered Questions

[SOLVED] How does the Java 'for each' loop work?

27 Answered Questions

[SOLVED] How to get an enum value from a string value in Java?

  • 2009-03-02 22:56:34
  • Malachi
  • 1141124 View
  • 2000 Score
  • 27 Answer
  • Tags:   java enums

43 Answered Questions

[SOLVED] How can I get useful error messages in PHP?

23 Answered Questions

[SOLVED] Does Java support default parameter values?

6 Answered Questions

[SOLVED] Returning from a finally block in Java

20 Answered Questions

Sponsored Content