有没有办法避免finally子句被执行?

时间:2011-06-03 14:40:50

标签: java

  

可能重复:
  Does a finally block always run?

我了解到try catch语句的finally子句总是执行。但有些人告诉我,可以避免执行它(删除它不是一种选择)。

- 有人怎么可能?

- 我很想知道为什么有人想避免执行它?

5 个答案:

答案 0 :(得分:6)

使用finally块中的未捕获异常来杀死它,或者杀死整个JVM(除了其他东西之外杀死线程)。

除了糟糕的设计之外,没有充分的理由停止执行finally块。如果它不应该每次运行,那么不要将它放在finally块中。


使用下面的测试代码,我运行两种不同的方案来查看杀死Thread时会发生什么:

  1. 启动Threadsleep主线程2秒钟。在Thread内,几乎立即进入finally块然后再睡5秒钟。主线程完成等待后,使用Thread终止stop
  2. 启动Thread并睡2秒。在Thread内,在进入finally区块前5秒钟睡觉,然后在finally内再睡一会儿,让它有机会被杀死。
  3. 在第一种情况下,结果是finally块停止执行。 在第二种情况下,结果是finally块完全执行,而Thread上的stop块执行不少。

    输出(注意为所有输出添加的当前线程的名称):

    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]
    

    代码:

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

答案 1 :(得分:4)

- 有人怎么可能?

System.exit(0);

- 我很想知道为什么有人想避免执行它?

To answer questions like these and appear smart. ;)

BTW,Thread.stop()不会阻止调用finally

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

打印

Thread start
Thread threw an error java.lang.ThreadDeath
Thread finally

答案 2 :(得分:0)

除非发生外部事件,例如Java虚拟机关闭,否则无法避免它。

作为一般规则,您应该始终假设将运行finally块。它的重点是确保它运行而不管try块中发生了什么 - 应该没有理由避免它!

答案 3 :(得分:0)

对于你的第一个问题,我认为我想到的唯一方法就是创造一个无限循环或其他东西。(但它完全没有意义)

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

对于你的第二个问题,我真的不知道为什么有人想做那样的事情

请参阅此链接:https://stackoverflow.com/posts/6228601/edit

答案 4 :(得分:0)

我想不出你想要避免最终阻止的一个好理由。如果你真的不想使用这个功能,那么就不要实现finally块(但需要自担风险)。

杀死JVM会做到这一点,但对于任何生产代码来说,这都不是一个可以接受的解决方案。

为什么删除finally块不是一个选项?