1

Possible Duplicate:
Does a finally block always run?

I learned that the finally clause of a try catch statement, executes always. But some guy said to me that it is possible to avoid executing it(removing it is not an option).

-Does someone how is that possible?

-Also i am curious in knowing why would someone want to avoid to execute it?

Community
  • 1
  • 1
javing
  • 12,307
  • 35
  • 138
  • 211
  • 1
    See http://stackoverflow.com/questions/464098/does-a-finally-block-always-run – Ben Jun 03 '11 at 14:43
  • Also see this post-> [how-to-use-finally](http://stackoverflow.com/questions/3354823/how-to-use-finally) – CoolBeans Jun 03 '11 at 14:46

5 Answers5

6

Kill it with an uncaught exception within the finally block, or kill the overall JVM (which kills the thread, among other things).

There is no good reason to stop the execution of a finally block except poor design. If it's not supposed to run every time, then don't put it in a finally block.


Using the below test code, I run two different scenarios to see what happens when killing the Thread:

  1. Start the Thread and sleep the main thread for 2 seconds. Within the Thread, pretty much immediately enter the finally block and then sleep for 5 seconds. Once the main thread is finished waiting, kill the Thread using stop.
  2. Start the Thread and sleep 2 seconds. Within the Thread, sleep 5 seconds before entering the finally block and then sleep some more within the finally to give it a chance to be killed.

In the first case, the result is that the finally block stops executing. In the second case, the result is that the finally block executes completely, and on the Thread that was stopped no less.

Output (note the name of the current thread added for all output):

thread-starting [main]
trying [Thread-0]
catching [Thread-0]
finally-sleeping [Thread-0]
thread-stopped [main]
 [main]
thread-starting [main]
trying-sleeping [Thread-1]
thread-stopped [main]
finally-sleeping [Thread-1]
finally-done [Thread-1]

Code:

public class Main
{
    public static void main(String[] args)
    {
        testThread(new TestRunnable());
        println("");
        testThread(new TestRunnable2());
    }

    private static void testThread(Runnable runnable)
    {
        Thread testFinally = new Thread(runnable);

        println("thread-starting");

        testFinally.start();

        try
        {
            Thread.sleep(2000);
        }
        catch (InterruptedException e)
        {
            println("main-interrupted...");
        }

        testFinally.stop();

        println("thread-stopped");
    }

    private static class TestRunnable implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                println("trying");
                throw new IllegalStateException("catching");
            }
            catch (RuntimeException e)
            {
                println(e.getMessage());
            }
            finally
            {
                println("finally-sleeping");

                try
                {
                    Thread.sleep(5000);
                }
                catch (InterruptedException e)
                {
                    println("finally-interrupted");
                }

                println("finally-done");
            }
        }
    }

    private static class TestRunnable2 implements Runnable
    {
        @Override
        public void run()
        {
            try
            {
                println("trying-sleeping");

                Thread.sleep(5000);
            }
            catch (InterruptedException e)
            {
                println("trying-interrupted");
            }
            finally
            {
                println("finally-sleeping");
                try
                {
                    Thread.sleep(5000);
                }
                catch (InterruptedException e)
                {
                    println("finally-interrupted");
                }
                println("finally-done");
            }
        }
    }

    private static void println(String line)
    {
        System.out.printf("%s [%s]%n", line, Thread.currentThread().getName());
        System.out.flush();
    }
}
pickypg
  • 22,034
  • 5
  • 72
  • 84
  • I agree -- System.exit(...) will prevent the finally from executing. – Liv Jun 03 '11 at 14:44
  • You can't kill the Thread in a way which avoid the finally block without killing the JVM. e.g. Thread.stop() still calls finally blocks. – Peter Lawrey Jun 03 '11 at 14:44
  • @Peter I meant to add "by throwing an uncaught exception within the `finally` block" but it for some reason blanked when I started typing. Will edit, which actually has less to do with the `Thread` as my brain is thinking at the moment. – pickypg Jun 03 '11 at 14:46
  • 1
    Evil thought - You can make the JVM run out of memory in the `try` block and that will make `finally` not execute :P – CoolBeans Jun 03 '11 at 14:47
  • @Peter are you sure about that? See http://stackoverflow.com/questions/464098/does-a-finally-block-always-run/464102#464102 – matt b Jun 03 '11 at 14:49
  • @matt I think this might be a long held myth. I heard that a long time ago and simply agreed with it (`Thread.stop()` does not prevent `finally` executing). I'm going to make a small example to test that theory. – pickypg Jun 03 '11 at 14:55
  • @matt b, Perhaps there is a way of "killing" a thread I wasn't aware of which doesn't kill the JVM, but you cannot stop() a thread without calling the finally block. – Peter Lawrey Jun 03 '11 at 14:57
  • Would love to see some example code for this theory; since the quote comes from a Sun tutorial it is pretty official-sounding. Note though they might be referring to another way of killing or interrupting the thread than `Thread.stop()` – matt b Jun 03 '11 at 15:04
  • @matt I hadn't noticed Peter's concise example below, but I added my own with a small twist as well (killing the `Thread` while in the `finally` block). – pickypg Jun 03 '11 at 15:42
4

-Does someone how is that possible?

System.exit(0);

-Also i am curious in knowing why would someone want to avoid to execute it?

To answer questions like these and appear smart. ;)

BTW, Thread.stop() doesn't prevent finally being called.

Thread t = new Thread() {
    @Override
    public void run() {
        try {
            System.out.println("Thread start");
            Thread.sleep(1000);
            System.out.println("Thread end");
        } catch (InterruptedException ie) {
            System.out.println("Thread Interrupted");
        } catch (Error e) {
            System.out.println("Thread threw an error " + e);
            throw e;
        } finally {
            System.out.println("Thread finally");
        }
    }
};
t.start();
t.join(100);
t.stop();

prints

Thread start
Thread threw an error java.lang.ThreadDeath
Thread finally
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
0

There's no way of avoiding it, unless something external happens such as the Java Virtual Machine shutting down.

As a general rule you should always assume that a finally block will run. The whole point of it is to ensure that it runs regardless of what happens in the try block - there should be no reason to avoid it!

0

To your first question i think the only way that comes to my mind is by creating an infinite loop or something.(But it makes no sense at all)

try{
    while(true);
}
catch(Exception e) {
}
finally {
//..
}

To your second question, i don't really know why would someone want to do something like that

See this link: https://stackoverflow.com/posts/6228601/edit

Community
  • 1
  • 1
javing
  • 12,307
  • 35
  • 138
  • 211
0

I can't think of a good reason that you would want to avoid a finally block. If you really don't want to use this feature, then just don't implement a finally block (at your own risk however).

Killing the JVM would do it, but that's not really an acceptible solution for any production code.

Why is removing a finally block not an option?

Dave
  • 1,303
  • 7
  • 19