Java 中的 `try-catch-finally` 与 `try-with-resource`

Java 中的 try-catch-finallytry-with-resource

〇、其他相关博客

Java异常详解

https://blog.csdn.net/qq_29689343/article/details/95736854

一、try-catch-finally 捕获和处理异常

1、概述

简介

try-catch-finally是最基本的异常处理机制。它由三个关键字组成:trycatchfinally。代码块放在try块中,如果在执行该块时抛出了异常,就会跳转到catch块中进行异常处理。finally块中的代码始终都会被执行,无论是否有异常发生。

try块后可跟零个、一个或多个catch块,如果没有catch块,则必须跟一个finally块。

finally 执行机制

无论是否捕获到异常,finally块大都会被执行!

有不会被执行到的可能:

  1. 如果在try或catch块中出现了System.exit()方法,JVM会立即终止程序,导致finally块不被执行。
  2. 如果在执行到finally块之前,JVM发生了内部错误或系统崩溃,那么finally块也将不会被执行。
  3. 如果程序所运行的线程被强制终止(如使用Thread.stop()方法),那么finally块也可能不会被执行。
  4. 如果try或catch块中发生了无限循环,那么finally块将永远无法被执行。

2、代码格式

try {
    
    
    // 可能抛出异常的代码
    // ...
} catch (ExceptionType1 e1) {
    
    
    // 处理 ExceptionType1 异常
    // ...
} catch (ExceptionType2 e2) {
    
    
    // 处理 ExceptionType2 异常
    // ...
} finally {
    
    
    // 在任何情况下都会执行的代码
    // ...
}

3、最佳实践

  1. 在try块中包含可能会抛出异常的代码。将可能引发异常的代码放在try块中,以便能够捕获和处理异常。
  2. 在catch块中捕获并处理异常。在catch块中,您可以指定要处理的异常类型,并提供异常处理程序。这可以确保程序在出现异常时不会崩溃,而是能够继续执行
  3. 不要忽略异常。在处理异常时,不要将异常抛出到方法调用者中,而是应该使用合适的异常处理程序来处理异常。这样可以使代码更加健壮和可靠。
  4. 使用多个catch块。如果代码可能抛出多种类型的异常,可以使用多个catch块来捕获和处理每种类型的异常。这样可以更好地控制异常处理过程,并确保代码能够正确处理每种类型的异常。
  5. 在finally块中释放资源。在finally块中,您可以指定要在代码执行完毕后执行的代码。这通常用于释放资源,例如关闭文件或网络连接等。无论代码是否抛出异常,finally块中的代码都会得到执行。
  6. 尽量使用局部变量。在try块中使用局部变量可以减少异常的影响范围,使得代码更容易理解和维护。
  7. 避免在finally块中抛出异常。如果在finally块中抛出异常,可能会导致代码变得更加复杂和难以理解。因此,应该在finally块中避免抛出异常,而是使用合适的异常处理程序来处理异常。
  8. 谨慎使用return语句:在try块、catch块和finally块中使用return语句时要小心,确保逻辑正确并符合预期。finally块中的return语句可能会覆盖try块或catch块中的return语句。

二、try-with-resources 自动关闭资源

1、概述

try-with-resources是从Java 7开始引入的一种异常处理机制。它用于自动关闭实现了 java.lang.AutoCloseable 接口或 java.io.Closeable资源,如文件或网络连接,以确保它们正确地关闭,即使在发生异常时也能被关闭。

使用try-with-resources时,我们可以在try语句中声明一个或多个资源,并在代码块结束后自动关闭这些资源。资源的声明和初始化以分号分隔。

2、代码示例

try (ResourceType1 resource1 = new ResourceType1(); ResourceType2 resource2 = new ResourceType2()) {
    
    
    // 使用 resource1 和 resource2 的代码
    // ...
} catch (ExceptionType e) {
    
    
    // 处理异常
    // ...
}

在上述示例中,ResourceType1ResourceType2 是实现了AutoCloseable接口的资源类型。它们在try块中声明和初始化,并在代码块结束后自动关闭。如果发生异常,程序将跳转到相应的catch块进行异常处理,并且在那之前资源会被自动关闭

3、try-with-resources 中 try catch finally 三个代码块

try-with-resources语句中,可以包含try块、catch块和finally块,它们的含义和作用**与传统的try-catch-finally块相同。**下面对它们进行详细解释:

  1. try块:try块包含需要进行异常处理的代码。在try块中,我们可以声明和初始化一个或多个资源对象,这些资源对象必须实现AutoCloseable接口或其子接口Closeabletry块中的代码在执行完毕后,无论是否发生异常,都会自动关闭这些资源。
  2. catch块:catch块用于捕获并处理try块中抛出的异常。它可以包含一个或多个catch子句,每个子句用于处理特定类型的异常。当在try块中的代码发生异常时,程序会跳转到匹配的catch块中,执行相应的异常处理代码。
  3. finally块:finally块中的代码在try块中的代码执行完毕后,无论是否发生异常,都会被执行。它通常用于执行一些必要的收尾操作,如释放资源、清理临时数据等。即使在try块或catch块中使用了return语句,finally块中的代码也会被执行。

代码示例

try (ResourceType resource = new ResourceType()) {
    
    
    // 可能抛出异常的代码
    // ...
} catch (ExceptionType e) {
    
    
    // 处理特定类型的异常
    // ...
} finally {
    
    
    // 在任何情况下都会执行的代码
    // ...
}

可以只有 try 块!

4、关闭资源

try-with-resources中,无论是否发生异常,资源都会被正确关闭。即使在try块中发生异常,也会执行资源的关闭操作。

try-with-resources语句执行完毕时,会自动调用每个资源对象的close()方法来关闭资源。这是通过编译器生成的字节码来实现的,确保资源的正确关闭。

如果在try块中发生异常,控制流会立即跳转到catch块或终止程序,但在跳转之前,编译器会调用每个资源对象的close()方法,确保它们被正确关闭。

这是try-with-resources相较于传统的try-catch-finally块的一个重要优势,它能够确保资源的自动关闭,无论是否发生异常。这样可以避免资源泄漏,并简化资源管理的代码。

5、最佳实践

  1. 使用try-with-resources来管理资源:对于需要手动关闭的资源,如文件、数据库连接等,尽量使用try-with-resources来自动管理资源的关闭。这样可以确保资源在使用完毕后被正确地关闭,避免资源泄漏。
  2. 实现AutoCloseable接口:要使用try-with-resources,资源类必须实现AutoCloseable接口或其子接口Closeable。这两个接口定义了close()方法,用于释放资源。确保资源类正确实现了这些接口。
  3. 只声明和初始化必要的资源:在try-with-resources语句中,只声明和初始化需要使用的资源。避免声明不必要的资源,以保持代码的清晰和简洁。
  4. 多个资源的处理:可以在try语句中声明和初始化多个资源,它们会按照声明的顺序依次关闭。每个资源的声明和初始化之间使用分号分隔。
  5. 资源的顺序:对于有依赖关系的资源,应按照正确的顺序声明和初始化它们,以确保依赖的资源在使用后能正确关闭。
  6. 异常处理:如果在try块中的代码抛出异常,try-with-resources会自动关闭已声明的资源,然后抛出最后一个异常。可以使用catch块捕获和处理该异常,或者将异常继续传递给上层调用者。
  7. 嵌套的try-with-resources:可以在一个try-with-resources语句中嵌套另一个try-with-resources语句。确保内部的资源在外部资源之前声明,以确保正确的关闭顺序。
  8. 使用合适的资源类型:选择适合的资源类型,这取决于资源的性质和需求。Java标准库中提供了许多实现了AutoCloseable接口的资源类,如FileInputStreamSocket等。也可以自定义实现AutoCloseable接口的资源类。

猜你喜欢

转载自blog.csdn.net/qq_29689343/article/details/131343221