在 Java 中处理异常时,通常需要使用 try-catch 块来处理它们,而不仅仅是将处理委托给调用这部分代码的人。然而,有时无论是否抛出异常,或者程序执行流程是否成功完成,都需要执行某些操作,例如关闭文件、数据库连接等。
对于这些情况,使用finally 块。该块放置在 catch 块之后,或者如果不使用 catch 块,甚至放置在 try 块之后。放置在finally块中的代码将在两种情况下执行:
让我们考虑一个除法方法,它接收两个整数并返回它们之间除法的结果。它使用 try-catch 块来处理尝试除以零时引发的异常,并使用 finally 块来打印一条消息,指示正在清理资源。
public static int divide(int a, int b) { try { return a / b; } catch (ArithmeticException e) { System.out.println("Error: " + e.getMessage()); throw e; } finally { System.out.println("Cleaning up resources..."); } }
通过使用值10和2调用divide方法,将获得以下输出:
Cleaning up resources... 5
正如我们所见,没有抛出异常,因此该方法返回了除法的结果,并且执行了finally块,尽管finally块的输出首先显示。另一方面,如果使用值10和0调用divide方法,将获得以下输出:
Error: / by zero Cleaning up resources... Exception in thread "main" java.lang.ArithmeticException: / by zero ...
在这种情况下,抛出了异常,因此执行流程被中断,并执行了catch块,但在再次抛出异常之前,执行了finally块。在这两个示例中,我们都看到无论获得的结果如何,finally 块总是被执行。
finally 块的主要用途是释放 try 块中已使用的资源,例如关闭文件、数据库连接或网络连接。为了举例说明这一点,让我们考虑一个 readFile 方法,该方法读取文件的内容并返回第一行。它使用 try-catch 块来处理无法读取文件时引发的异常,并使用 finally 块来关闭文件。
public static String readFile() throws IOException { FileReader reader = null; try { reader = new FileReader("file.txt"); BufferedReader buffer = new BufferedReader(reader); return buffer.readLine(); } catch (IOException e) { System.out.println("Error: " + e.getMessage()); throw new RuntimeException(e); } finally { if (reader != null) reader.close(); } }
如果执行readFile方法而无法读取文件,则会得到以下输出:
public static int divide(int a, int b) { try { return a / b; } catch (ArithmeticException e) { System.out.println("Error: " + e.getMessage()); throw e; } finally { System.out.println("Cleaning up resources..."); } }
我们可以看到,抛出了异常,因此执行流程被中断,并执行了catch块,但在再次抛出异常之前,执行了finally块以关闭文件。另一方面,如果创建一个 file.txt 文件,其内容为 Hello world!调用 readFile 方法,将获得以下输出,不会抛出任何异常:
Cleaning up resources... 5
此示例中需要考虑的一些方面是:
finally 在 Java 中的使用已经变得如此普遍,以至于语言本身有一个替代方案可以让我们简化资源管理,即 try-with-resources 块。该块负责在资源使用结束时自动关闭资源,因此无需使用finally 块来释放资源。但是,需要注意的是,finally 块在某些情况下仍然有用,并且两个选项可以一起使用。
以上是Java中的finally块的详细内容。更多信息请关注PHP中文网其他相关文章!