Java AutoCloseable
最后修改于 2025 年 4 月 2 日
AutoCloseable 接口是 Java 资源管理系统的一个基本组成部分,在 Java 7 中引入。它通过 try-with-resources 语句实现自动资源管理,确保资源的正确清理。
在本教程中,我们将探讨如何使用 AutoCloseable 安全有效地管理文件、数据库连接和网络套接字等资源。我们将介绍内置实现和自定义资源类。
理解 AutoCloseable
AutoCloseable 是一个只有一个方法的接口
public interface AutoCloseable { void close() throws Exception; }
任何实现 AutoCloseable 的类都可以与 try-with-resources 一起使用。当 try 块退出时,无论正常退出还是异常退出,都会自动调用 close() 方法。
Try-With-Resources 基础
try-with-resources 语句自动关闭实现 AutoCloseable 的资源。 这是基本语法
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; void readFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } }
即使发生异常,BufferedReader
也会在 try 块完成后自动关闭。 这消除了手动 finally 块的需要。
多个资源
您可以在单个 try-with-resources 语句中声明多个资源
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.ZipInputStream; void copyZipFile(File source, File target) throws IOException { try (InputStream in = new FileInputStream(source); OutputStream out = new FileOutputStream(target); ZipInputStream zipIn = new ZipInputStream(in)) { byte[] buffer = new byte[1024]; int length; while ((length = zipIn.read(buffer)) > 0) { out.write(buffer, 0, length); } } }
资源以声明的相反顺序关闭。 如果任何资源无法关闭,其他资源仍会尝试关闭。
创建自定义 AutoCloseable 资源
您可以为自定义资源创建自己的 AutoCloseable 实现
class DatabaseConnection implements AutoCloseable { private boolean isOpen = true; public void executeQuery(String query) { if (!isOpen) { throw new IllegalStateException("Connection closed"); } System.out.println("Executing: " + query); } @Override public void close() { if (isOpen) { System.out.println("Closing database connection"); isOpen = false; } } } void useDatabase() { try (DatabaseConnection conn = new DatabaseConnection()) { conn.executeQuery("SELECT * FROM users"); } }
这个自定义 DatabaseConnection 演示了正确的资源清理模式。 close
方法是幂等的(可以安全地多次调用)。
被抑制的异常
当 try 块中和资源关闭期间都发生异常时,关闭异常会被“抑制”并附加到主要异常
class FailingResource implements AutoCloseable { @Override public void close() throws Exception { throw new Exception("Error during close"); } public void use() throws Exception { throw new Exception("Error during use"); } } void demonstrateSuppressed() { try (FailingResource res = new FailingResource()) { res.use(); } catch (Exception e) { System.out.println("Caught: " + e.getMessage()); for (Throwable t : e.getSuppressed()) { System.out.println("Suppressed: " + t.getMessage()); } } }
此示例显示了如何访问在资源清理期间发生的被抑制的异常。
AutoCloseable vs Closeable
Closeable 是一个类似于 AutoCloseable 的接口,但出现的时间更早。 主要区别:
interface Closeable extends AutoCloseable { void close() throws IOException; // More specific exception }
- Closeable 抛出 IOException,AutoCloseable 抛出 Exception
- Closeable 适用于 I/O 流
- Closeable 需要幂等的 close() 操作
- AutoCloseable 用途更广泛
最佳实践
使用 AutoCloseable 时
- 始终对 AutoCloseable 对象使用 try-with-resources
- 使 close 方法幂等(可以安全地多次调用)
- 以相反的获取顺序释放资源
- 适当处理被抑制的异常
- 对于新的资源类型,首选 AutoCloseable
- 记录资源所有权和清理要求
来源
本教程涵盖了 Java AutoCloseable 接口和 try-with-resources 语句的基本方面,以便在 Java 应用程序中进行适当的资源管理。
作者
列出所有Java教程。