为什么 finally 在 java 中有用?

Why is finally useful in java?

我想知道为什么 finallytry catch 测试后有用?在任何场景下,定义在finally语句之后的代码都会被执行。

这两个代码有什么区别?

try{
    int a = 1 / 0;
} catch(ArithmeticException e){
    System.out.print("Hi");
} finally {
    System.out.print("It's me again...");
}

和:

    try{
    int a = 1 / 0;
} catch(ArithmeticException e){
    System.out.print("Hi");
}
System.out.print("It's me again...");

即使捕获到错误,也会显示"It's me again..."..

来自 docs

This ensures that the finally block is executed even if an unexpected exception occurs.

请注意 意外 一词。您显示的是预期的异常。

finally 块通常用于执行最终操作,即使在代码中间出现某些异常时也是如此。

一个示例是在 finally 块中关闭文件。

对于初学者来说,如果 System.out 流被关闭,并且 catch 块因此引发异常,那么 finally 块仍然是执行。所以两者不等价。所以在以下情况下:

System.out.close();
try{
    int a = 1 / 0;
} catch(ArithmeticException e){
    System.out.print("Hi");
} finally {
    System.out.print("It's me again...");
}

最后至少会尝试写入out。如果您在 try-catch 之后 编写它,情况就不会如此。

finally 之所以有用,有几个原因:

  1. try 块中的代码通常有可能引发 catch 块中指定的另一个异常,那么finally仍然会被执行。

  2. 如果在try块中有return/break/continue语句try 块之外有效(例如 breakfor 循环中的 try 中),如果你在 [=15 之后写它,它不会被执行=],那么 finally 也会被调用。这也会产生更优雅的代码。例如:

    BufferedReader br = new BufferedReader(new FileReader("file.txt"));
    
    try {
        <b>return</b> br.readLine();
    } finally {
        br.close();
    }
    

    注意 return 语句:如果你要在没有 finally 的情况下执行文件的 close,它会要求你定义一个变量等。读取文件出错,当然不会关闭文件)。

  3. 如果 catch 块依次抛出异常,最终将再次执行。

它还允许您在抛出异常后执行一些操作,但不捕获异常:如果从未捕获到异常,则会进一步抛出异常。如果是:

try {
    throw new SomeException("The culprit!");
} finally {
    System.out.println("Some closing words.");
}

构造的 SomeException 及其堆栈跟踪不是 finally 块 "toched":堆栈跟踪未更改。这样 bugfixer 就可以找出异常最初抛出的位置。

一般来说,最好在 finally 中写下离开 try-catch(有零个或多个 catches)块之前必须完成的所有事情,因为它保护你反对各种极端情况。

更深入编程语言理论,returnbreakcontinuethrow等都是代码路径改变机制。 finally 声明保证在发生此类行为时您会受到保护。如果以后 Java 的设计者引入一种新机制,您的代码仍然是 "protected"。始终建议使用编程语言提供的基础设施,因为设计人员考虑了所有这些可能性。