开发者

Is there any way to avoid the finally clause to get executed? [duplicate]

This question already has answers here: Closed 11 years ago.

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?


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


-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


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!


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


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?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜