在Java中,是否保证调用“finally”块(在main方法中)?

2022-09-01 18:04:22

我是一个Java新手,我想知道,如果我有以下典型的Java代码

public class MyApp {
  public static void main(String[] args) {
    try {
      // do stuff
    } catch {
      // handle errors
    } finally {
      // clean up connections etc.
    }
  }
}

JVM 是否保证最终块将始终运行?为了理解我来自哪里,我习惯于C / C++程序,如果您取消引用NULL指针,并且在此之后无法运行任何代码,这些程序可能会崩溃。

但是,当我了解Java和整个GC /托管内存业务时,没有空指针取消引用这样的事情,一切都是可捕获的期望,所以我的程序实际上没有办法崩溃,可以让它最终跳过,还是有?例如,在Python中,我通常做

try:
  # do stuff
except AnExceptionIKnewMightHappen:
  # react in an appropriate way
except:
  # log that weird error I had not known could happen

我从来没有任何应用程序在不传递我的代码的情况下死亡。

当然,如果操作系统由于某种原因杀死了进程(或者如果某些东西杀死了整个系统,比如拔掉插头),那么Java就无能为力了。另外,从PHP中,我知道无法防止的不可捕获的错误,即使解释器在发生后仍然存在(至少它能够输出正确的消息)。

编辑:为了清楚起见(它没有被任何人误解),让我补充一点,我正在我的代码中寻找可能导致最终被绕过的东西。因此,指向System.exit是一个有用的提醒,即使我不明白为什么我想做这样的事情。

JVM退出是一种相当明显的方式,我认为这是一个外部原因。指出您还必须记住在JVM和应用程序继续运行时线程退出的可能性的注释非常有帮助,因为即使现在对我来说也很明显,但我没有想到它。


答案 1

基本上是的,除了这里列出的注释(强调我的):

如果 JVM 在执行 try 或 catch 代码时退出,则 finally 块可能不会执行。同样,如果执行 try 或 catch 代码的线程被中断或终止,则即使应用程序作为一个整体继续,finally 块也可能不会执行。


答案 2

不保证:

public class Main {
    public static void main(String args[]) {
        try {
            System.out.println("try");
            System.exit(0);
        } catch (Exception e) {
            System.out.println("exception");
        } finally {
            System.out.println("finally");
        }
    }
}

运行它。


推荐