2009-02-05 21 views
22

我是一个Java的菜鸟,我想知道,如果我有以下典型的Java代码在Java中,保证被调用的“finally”块(在主要方法中)?

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

并在JVM保证finally块将始终运行?为了理解我来自哪里,我习惯于C/C++程序,如果您解除引用空指针并且在此之后不能运行任何代码,那么C/C++程序可能会崩溃。

但是,据我所知,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

啧啧,那是很快的答案。显然是一个很noob问题。不管怎么说,还是要谢谢你! – 2009-02-05 14:22:51

+0

答案是否,详情请参阅:http://tshikatshikaaa.blogspot.nl/2012/07/about-using-systemexit-in-try-catch.html – JVerstry 2012-07-29 15:56:36

回答

41

基本上是,除了注listed here(重点煤矿):

如果JVM退出,而尝试或挂钩代码正在执行, 然后最后的块可能不会执行。同样,如果执行try或catch代码的线程 被中断或终止,则尽管应用程序整体 仍在继续,但最终 块可能不会执行

+15

请注意,拉动电源线通常是预防“finally”from running,too ... – 2009-02-05 14:43:55

+3

LOL - 如果是笔记本电脑,笔记本电脑中的电池会在同一时刻死亡:D – 2009-02-05 15:59:36

+5

将笔记本电脑从天空刮板的顶部故事中剔除,和*关机挂钩! – 2009-02-06 07:02:11

0

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

显然,如果你打破了JVM :)它不会运行

0

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

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

运行这一点。

8

总而言之,是的。

代码在Java中的finally块总是执行,除非:

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

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

所以,除非你明确地调用System.exit(INT),或杀掉进程或线程外,你可以依靠它。

3

当然,最终块会运行,每次。除了JVM崩溃或调用exit()函数的情况。我已经有了代码,Java应用程序会将这些代码发送给隔离的JNI本机代码。由此产生的崩溃终止了JVM,并阻止了最终的运行。

2

克里斯卡梅隆是正确的。但通常会执行finally - 块。 Java中存在空指针取消确认:

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

finally块被执行。

1

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

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

0

finally块中唯一没有执行的异常是JVM崩溃或system.exit()。

0

看起来很明显,没有什么更多的将在JVM退出后运行,或者将在该死的线程中运行代码。明显。因此,当JVM运行时,每个将运行的代码都将运行,并且在JVM退出之后或在死线程中,将不会运行任何甚至任何类型的代码。所以,没有办法预防,但如果需要最后的条款,把它。