Java中的try-with-resources语法
本文最后更新于 2025-10-30,文章内容可能已经过时。
一、基本概念
try-with-resources是Java 7引入的一项重要语法糖,用于自动管理需要显式关闭的资源(如文件流、数据库连接、网络连接等)。它简化了资源管理的代码,避免了手动编写try-catch-finally块来关闭资源的繁琐操作。
核心特点:
- 自动关闭资源:无需手动调用
close()方法 - 确保资源正确关闭:无论代码正常结束还是抛出异常
- 代码更加简洁:减少冗余代码,提高可读性
- 防止资源泄漏:降低内存泄漏和文件锁定的风险
二、语法结构
try (ResourceType resource = new ResourceType()) {
// 使用资源的代码
} catch (ExceptionType e) {
// 异常处理
}
多资源声明(用分号分隔):
try (ResourceType1 resource1 = new ResourceType1();
ResourceType2 resource2 = new ResourceType2()) {
// 使用多个资源的代码
} catch (ExceptionType e) {
// 异常处理
}
三、关键要求
-
资源必须实现AutoCloseable接口:
AutoCloseable接口要求类实现void close()方法- 实现了该接口的类才能被自动关闭
-
常见AutoCloseable实现类:
InputStream、OutputStream及其子类(如FileInputStream,BufferedReader等)java.sql.Connection、java.sql.Statement、java.sql.ResultSetjava.nio.channels.FileChannel等Socket、ServerSocket等网络连接类
四、详细使用示例
示例1:读取文件内容(单资源)
import java.io.*;
public class FileReadingExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.err.println("读取文件时出错: " + e.getMessage());
}
}
}
解析:
BufferedReader实现了AutoCloseable接口- 无需手动调用
br.close(),资源会在try块结束后自动关闭 - 即使发生异常,资源也会被正确关闭
示例2:读取和写入文件(多资源)
import java.io.*;
public class FileCopyExample {
public static void main(String[] args) {
try (FileReader fr = new FileReader("input.txt");
BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter("output.txt")) {
String line;
while ((line = br.readLine()) != null) {
fw.write(line);
fw.write("\n"); // 保持原文件格式
}
System.out.println("文件复制成功!");
} catch (IOException e) {
System.err.println("文件操作失败: " + e.getMessage());
}
}
}
解析:
- 同时声明了三个资源:
FileReader、BufferedReader和FileWriter - 资源会按照声明的逆序关闭(先关闭
FileWriter,再BufferedReader,最后FileReader) - 无需担心资源关闭顺序问题
示例3:数据库连接处理
import java.sql.*;
public class DatabaseExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "username";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println("ID: " + rs.getInt("id") +
", Name: " + rs.getString("name"));
}
} catch (SQLException e) {
System.err.println("数据库操作失败: " + e.getMessage());
}
}
}
解析:
- 数据库连接、语句和结果集都实现了
AutoCloseable接口 - 按照
ResultSet→PreparedStatement→Connection的顺序自动关闭 - 符合数据库资源的清理依赖关系
示例4:自定义资源(实现AutoCloseable)
import java.io.*;
public class CustomResourceExample {
public static void main(String[] args) {
try (MyResource resource = new MyResource()) {
resource.doWork();
} catch (Exception e) {
System.err.println("操作失败: " + e.getMessage());
}
}
}
class MyResource implements AutoCloseable {
public MyResource() {
System.out.println("资源已打开");
}
public void doWork() {
System.out.println("正在执行工作...");
// 模拟工作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void close() {
System.out.println("资源已关闭");
}
}
输出:
资源已打开
正在执行工作...
资源已关闭
解析:
- 自定义类
MyResource实现了AutoCloseable接口 close()方法会在try块结束后自动调用- 适用于任何需要资源管理的场景
五、资源关闭顺序
当在try-with-resources中声明多个资源时,它们会按照声明的逆序自动关闭。即最后声明的资源最先关闭。
try (ResourceA a = new ResourceA();
ResourceB b = new ResourceB();
ResourceC c = new ResourceC()) {
// 使用资源
} // 关闭顺序: c → b → a
这种顺序通常符合依赖关系的清理顺序,例如:
- 数据库连接(Connection)需要在结果集(ResultSet)和语句(Statement)关闭之后关闭
- 文件读取流(BufferedReader)需要在文件流(FileReader)关闭之后关闭
六、异常处理
如果在try块中发生异常,或在关闭资源过程中发生异常,Java会将关闭异常作为被抑制异常(suppressed exception)添加到主要异常中。
try (FileInputStream fis = new FileInputStream("file.txt")) {
// 操作文件
} catch (IOException e) {
// 获取被抑制的异常
for (Throwable suppressed : e.getSuppressed()) {
System.err.println("被抑制的异常: " + suppressed.getMessage());
}
}
七、与传统try-catch-finally对比
传统方式(冗长且易出错)
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try-with-resources方式(简洁高效)
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
八、注意事项
- 资源必须实现AutoCloseable:不能用于未实现该接口的资源
- 资源初始化:资源必须在try括号内初始化
- 资源关闭顺序:按声明的逆序关闭
- 不能重复使用:try-with-resources中的资源只能在try块中使用
- Java版本要求:需要Java 7或更高版本
九、总结
try-with-resources是Java 7引入的语法糖,通过自动管理资源关闭,使代码更加简洁、安全。它适用于任何实现了AutoCloseable接口的资源,如文件流、数据库连接等。使用try-with-resources可以显著减少代码量,降低资源泄漏风险,提高代码的可维护性。
在Java 7及以上版本中,推荐优先使用try-with-resources语法来管理资源,而不是传统的try-catch-finally方式。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 软件从业者Hort
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果

