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

我是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和应用程序继续运行时退出的线程的可能性是非常有帮助的,因为即使它现在对我来说似乎也很明显,但我没有想到它。

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

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

不保证:

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

跑吧。

总之,是的。

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

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

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

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

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

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

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

finally块被执行。

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

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

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

如果你打破jvm显然它不会运行:)

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

最终阻止的唯一exception是JVM崩溃,或者是system.exit()。

似乎很明显,在JVM退出之后不会再运行,或者将在该被杀死的线程中运行代码。 明显。 因此,当JVM运行时,每个将运行的代码都将运行,并且在JVM退出或在死线程内部之后, 什么都不会运行,甚至任何类型的代码。 所以,没有办法防止,但如果需要finally子句,就把它放进去。