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

sfr*_*frj 0 java

可能重复:
finally块是否始终运行?

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

- 有人怎么可能?

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

pic*_*ypg 6

finally块中杀死未捕获的异常,或杀死整个JVM(杀死线程等).

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


使用下面的测试代码,我运行两个不同的场景,看看杀死时会发生什么Thread:

  1. 启动Threadsleep主线程为2秒.在其中Thread,几乎立即进入finally块,然后睡5秒.一旦主线程完成等待,杀死Thread使用stop.
  2. 开始Thread并睡2秒.在其中Thread,在进入finally街区之前睡5秒,然后再在其中睡一会儿finally,让它有机会被杀死.

在第一种情况下,结果是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]
Run Code Online (Sandbox Code Playgroud)

码:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)