finally {}块不会执行的情况是什么? [英] What are the circumstances under which a finally {} block will NOT execute?

查看:137
本文介绍了finally {}块不会执行的情况是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java 中尝试{} ... catch {} ... finally {} 阻止,中的代码最终{} 通常被认为是保证运行。但是,我知道至少有两种情况,执行:

In a Java try{} ... catch{} ... finally{} block, code within the finally{} is generally considered "guaranteed" to run regardless of what occurs in the try/catch. However, I know of at least two circumstances under which it will not execute:


  • 如果调用System.exit(0);或者,

  • 如果异常被抛出到JVM并且出现默认行为(即 printStackTrace()并且退出)

  • If System.exit(0) is called; or,
  • if an Exception is thrown all the way up to the JVM and the default behavior occurs (i.e., printStackTrace() and exit)

是否有任何其他程序行为会阻止中的代码最终{} 阻止执行?代码在什么具体条件下执行?

Are there any other program behaviors that will prevent the code in a finally{} block from executing? Under what specific conditions will the code execute or not?

编辑:由于NullUserException指出,第二种情况实际上并非如此。我认为这是因为标准错误中的文本在标准输出之后打印出来,防止文本在没有向上滚动的情况下被看到。 :)道歉。

As NullUserException pointed out, the second case is actually not true. I thought it was because the text in standard error printed after that in standard out, preventing the text from being seen without scrolling up. :) Apologies.

推荐答案

如果你打电话给 System.exit() 没有最后被调用。

If you call System.exit() the program exits immediately without finally being called.

JVM崩溃例如分段错误,也会阻止最终被调用。即JVM此时立即停止并生成崩溃报告。

A JVM Crash e.g. Segmentation Fault, will also prevent finally being called. i.e. the JVM stops immediately at this point and produces a crash report.

无限循环也会阻止最终被调用。

An infinite loop would also prevent a finally being called.

抛出Throwable时总是调用finally块。即使你调用Thread.stop()来触发 <要在目标线程中抛出code> ThreadDeath 。这可以被捕获(这是一个 错误 )将调用finally块。

The finally block is always called when a Throwable is thrown. Even if you call Thread.stop() which triggers a ThreadDeath to be thrown in the target thread. This can be caught (it's an Error) and the finally block will be called.

public static void main(String[] args) {
    testOutOfMemoryError();
    testThreadInterrupted();
    testThreadStop();
    testStackOverflow();
}

private static void testThreadStop() {
    try {
        try {
            final Thread thread = Thread.currentThread();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    thread.stop();
                }
            }).start();
            while(true)
                Thread.sleep(1000);
        } finally {
            System.out.print("finally called after ");
        }
    } catch (Throwable t) {
        System.out.println(t);
    }
}

private static void testThreadInterrupted() {
    try {
        try {
            final Thread thread = Thread.currentThread();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    thread.interrupt();
                }
            }).start();
            while(true)
                Thread.sleep(1000);
        } finally {
            System.out.print("finally called after ");
        }
    } catch (Throwable t) {
        System.out.println(t);
    }
}

private static void testOutOfMemoryError() {
    try {
        try {
            List<byte[]> bytes = new ArrayList<byte[]>();
            while(true)
                bytes.add(new byte[8*1024*1024]);
        } finally {
            System.out.print("finally called after ");
        }
    } catch (Throwable t) {
        System.out.println(t);
    }
}

private static void testStackOverflow() {
    try {
        try {
            testStackOverflow0();
        } finally {
            System.out.print("finally called after ");
        }
    } catch (Throwable t) {
        System.out.println(t);
    }
}

private static void testStackOverflow0() {
    testStackOverflow0();
}

打印

finally called after java.lang.OutOfMemoryError: Java heap space
finally called after java.lang.InterruptedException: sleep interrupted
finally called after java.lang.ThreadDeath
finally called after java.lang.StackOverflowError

注意:每个case线程保持运行,即使在SO,OOME,Interrupted和Thread.stop()之后!

Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!

这篇关于finally {}块不会执行的情况是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆