Java中finally块的要点是什么?

abu*_*tin 8 java exception-handling finally

我想以下例子; 但无法弄清楚finally块的重要性是什么.你能告诉我这两个代码示例的执行区别吗?现实生活中的例子也很有帮助.

样本1:

    try{
       // some code 1
    }catch(Exception ex){
       // print exception   
    }finally{
       // some code 2            
    }
Run Code Online (Sandbox Code Playgroud)

样本2:

    try{
      // some code 1
    }catch(Exception ex){
      // print exception   
    }
    // some code 2
Run Code Online (Sandbox Code Playgroud)

pol*_*nts 17

你提出的两个片段有很大的不同,例如当catch块本身抛出异常时,finally块仍将由其语义执行.

这是以下代码段打印"Finally!",但不是"What about me???":

    try {
        throw null;     // throws NullPointerException!
    } catch (Exception e) {
        int oops = 1/0; // throws ArithmeticException!
    } finally {
        System.out.println("Finally!"); // still gets executed!
    }
    System.out.println("What about me???"); // doesn't get executed!
Run Code Online (Sandbox Code Playgroud)

一般来说,finally一个的try实际上总是被执行.对try块后面的任何代码都没有这样的保证.


但是如果我的catch块只是一个简单的print陈述怎么办?

仍然无法保证它不会出现问题throw.在例如异常详细消息的构造中,仍然可能出现问题.

即使您尽最大努力保证catch代码是"安全的"并且try语句后面的代码将始终执行,那么问题就变成"为什么?".为什么要避免finally但是那么努力复制它的语义呢?

finally语义是有保证的,不需要代码的作者或读者的证据负担.也正因为如此,它是地道使用finally块把强制"清理"代码.使用finally保证正确性并增强可写性和可读性.


Pét*_*rök 8

finally即使例如Error抛出了一个块,也会执行该块,这不会被catch示例中的块捕获.因此,您可以将清理代码放在finally块中,该块应始终运行,而不管块trycatch块中的操作结果如何.

请注意,通常catch块会捕获更具体类型的异常 - 通常只检查异常 - 因此在大多数情况下,上面两个代码示例之间的差异是非常明确的.

更新:您可能会说您的catch块永远不会抛出异常,因此finally不需要.但请注意两件事:

  • 这只是代码的当前状态,并且它可以在将来改变 - 你能保证未来的程序员在catch块中添加一些可能引发异常的代码,会记得将清理代码放在一个finally块中吗?
  • try-catch-finally是一种编程习惯用法,使阅读代码的人更容易理解正在发生的事情.如果你不使用常用的习语,你就会产生误解,从而导致长期的错误.