当前位置: 首页 > 面试题库 >

在什么情况下,finally {}块将不执行?

池赞
2023-03-14
问题内容

在Java try{} ... catch{} ... finally{}块中,finally{}无论try /
catch中发生了什么,通常都认为其中的代码可以“保证”运行。但是,我知道至少有两种情况 不会 执行:

  • 如果System.exit(0)被调用;要么,
  • 如果异常一直抛出到JVM,并且发生默认行为(即printStackTrace()退出)

是否有其他程序行为会阻止finally{}块中的代码执行?代码将在什么特定条件下执行或不执行?

编辑:
正如NullUserException所指出,第二种情况实际上是不正确的。我以为是因为标准错误的文本在标准输出之后打印出来,从而阻止了文本的滚动显示。:)
道歉。


问题答案:

如果调用System.exit(),程序将立即退出而不finally被调用。

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

无限循环也将阻止finally被调用。

当抛出Throwable时,总是调用finally块。即使您调用Thread.stop()ThreadDeath也会触发将a
引发到目标线程中。可以捕获到它(是Error),并会调用finally块。

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

注意:在每种情况下,即使在SO,OOME,Interrupted和Thread.stop()之后,线程仍保持运行状态!



 类似资料:
  • 本文向大家介绍在什么情况下选择webpack?在什么情况下选择rollup?相关面试题,主要包含被问及在什么情况下选择webpack?在什么情况下选择rollup?时的应答技巧和注意事项,需要的朋友参考一下 非要一句话区分的话 如果是用,如果是用其实界限并不是特别明显。在某些特殊情况下可以互用

  • 本文向大家介绍datanode在什么情况下不会备份相关面试题,主要包含被问及datanode在什么情况下不会备份时的应答技巧和注意事项,需要的朋友参考一下 解答: 当分备份数为1时。

  • 问题内容: 今天,在浏览各种问题时,我遇到了一个问题,在我看来有点不可思议,为什么一个人要在上面加上a ,对于这种情况会不会有什么真正的原因,所以这只是微不足道的吗? 问题答案: 动画图像作为GUI的BG。我使用HTML来调整此尺寸(x3),但是如果它已经是所需的尺寸,则可以直接将其设置为标签的。 不知道它是否是“真正的”。这似乎是一个主观术语,需要更多说明。我从来没有使用过这种方法,只是想通了,

  • 问题内容: 说我有一个清单。在什么情况下被称为? 我基本上理解了文档,但是我也想看到一个示例来毫无疑问地阐明其用法。 问题答案: 当Python尝试将两个对象相乘时,它首先尝试调用左侧对象的方法。如果左对象没有方法(或者该方法返回,表明它不适用于所讨论的右操作数),则Python希望知道右对象是否可以进行乘法。如果右操作数与左操作数的类型相同,Python就会知道它不能,因为如果左对象不能做到这一

  • 我正在windows(7.3版)上安装gvim。启动后,我希望设置变量MYVIMRC,但它没有设置。有没有理由不设定。 有一个vimrc文件,因为许多设置与默认设置不同。 我用检查了MYVIMRC的值 gvim可执行文件位于c:\workarea\Vim\vim73中,c:\workare\Vim中的*\u vimrc*(在gvim启动时读取)。启动gvim后,我可以使用 对于版本:我发现系统vi

  • 大家能不能结合自己的项目大小,说明一下。 哨兵+主从模式,会在多大数据量情况下出现性能瓶颈?