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

时间:2009-02-05 14:13:50

标签: java error-handling finally

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

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

JVM是否保证finally块始终运行?为了理解我来自哪里,我习惯了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和应用程序继续运行时退出的线程的可能性非常有用,因为即使现在对我来说这似乎也很明显,但我没有想到它。

10 个答案:

答案 0 :(得分:44)

基本上是的,除了注释listed here(强调我的):

  

如果在执行try或catch代码时JVM退出,   那么finally块可能不会执行。同样,如果线程   执行try或catch代码被中断或终止,最后   阻止可能不会执行即使应用程序整体   继续进行。

答案 1 :(得分:12)

无法保证:

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

运行它。

答案 2 :(得分:9)

总之,是的。

Java中的finally块中的代码始终执行,除非:

  • JVM在try或catch块期间退出
  • 运行代码的线程在try或catch块期间被中断或终止

(来自:http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html

因此,除非您显式调用System.exit(int),或者从外部终止进程或线程,否则您可以依赖它。

答案 3 :(得分:4)

当然,每次都会运行finally块。除了在JVM崩溃或调用exit()函数的情况下。我有一些代码,Java应用程序调用了JNI本机代码,这些代码是segfaulted。由此导致的崩溃导致JVM死亡,并阻止了终端运行。

答案 4 :(得分:2)

克里斯卡梅隆是对的。但通常会执行finally - 块。 Java中存在空指针dereferece:

try {
    List<Object> x = null;
    x.get(1); //throws the unchecked NullPointerException
} finally {
    //will be executed
}

终结块被执行。

答案 5 :(得分:1)

是的,JVM总是执行它。 Gaurranteed。

当然......如果JVM 本身死亡(例如:System.exit()),那么它就无法保证任何东西。但JVM死亡不是java内问题。

答案 6 :(得分:0)

嗯,是的:)无论你的代码是否输入了一个catch,finally都会运行。这是在尝试后清理代码的好地方。

显然,如果你破坏了jvm,它将无法运行:)

答案 7 :(得分:0)

是的,finally块将始终运行,除非JVM崩溃(非常罕见,但可能会发生)。

答案 8 :(得分:0)

唯一没有执行块的例外是JVM崩溃,或者是system.exit()。

答案 9 :(得分:0)

很明显,没有更多将在JVM退出后运行,或者将在该被杀死的线程中运行代码。明显。因此,当JVM运行时,每个将运行的代码都将运行,并且在JVM退出或在死线程内,将运行,甚至任何类型的代码。所以,没有办法防止,但如果需要finally子句,请把它放好。