繁体   English   中英

Java中finally块的要点是什么?

[英]What is the gist of finally block in Java?

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

样本1:

    try{
       // some code 1
    }catch(Exception ex){
       // print exception   
    }finally{
       // some code 2            
    }

样本2:

    try{
      // some code 1
    }catch(Exception ex){
      // print exception   
    }
    // some code 2

你提出的两个片段有很大的不同,例如当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!

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


但是,如果我的catch块只是一个简单的print声明呢?

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

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

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

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

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

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

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

您使用finally块来清理并运行任何应该运行的代码,无论是否抛出(和捕获)异常。 这包括catch块中的代码。

当我们想要释放我们在try块中使用的资源时,它会很有用。 因此,在任何情况下执行它们而不丢失的唯一地方是最终阻止。 因为如果抛出异常,java不会执行之后立即执行的代码。 它直接跳转到catch块。

请注意,您甚至可以在没有catch的情况下尝试finally:

try{
   // some code 
}finally{
   // cleanup code
}

因此,一个示例可能是一种想要将异常传播给调用者的方法,但仍需要清理代码,例如释放外观。

如果try块中的语句抛出未经检查的异常,则最终将执行块以允许程序员采取相关操作。

在现实生活中,即使发生异常,finally块也用于关闭打开的资源。 例如,当您读取(或写入)文件,访问数据库等时。

public void readFile(String fileName) {
    FileReader fr;
    BufferedFileReader bfr;

    try {
        fr = new FileReader(fileName);
        bfr = new BufferedFileReader(fr);
        // ...
    } catch (IOException ioe) {
        // ...
    } finally {
        // TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
        if (bfr != null) { 
            try {
                bfr.close();
            } catch (IOException ignoredIOE) {}
        }
        if (fr != null) { 
            try {
                fr.close();
            } catch (IOException ignoredIOE) {}
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM