Java try-with-resources 介绍
1. 什么是 try-with-resources?
try-with-resources 是 Java 7 引入的一个特性,用于自动管理资源(如文件流、数据库连接、网络连接等)。它确保每个资源在语句结束时自动关闭,无需显式编写 finally 块。
优点:
- 代码简洁:减少样板代码
- 安全可靠:自动确保资源关闭
- 异常处理更完善:保留原始异常,关闭异常作为抑制异常
- 可读性更好:清晰地看到资源声明和使用范围
2. 基本语法
try (ResourceType resource = new ResourceType()) {
// 使用资源的代码
} catch (ExceptionType e) {
// 异常处理
}3. 工作原理
- 资源必须实现
AutoCloseable或Closeable接口 - 在 try 块结束后,资源会按照声明的相反顺序自动关闭
- 资源关闭操作在 finally 块之前执行
4. 支持多资源
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}5. 异常处理机制
try-with-resources 提供了更优雅的异常处理机制:
public class ResourceExample {
static class Resource1 implements AutoCloseable {
public void use() throws Exception {
throw new Exception("异常发生在使用资源时");
}
@Override
public void close() throws Exception {
throw new Exception("异常发生在关闭资源时");
}
}
public static void main(String[] args) {
try (Resource1 r1 = new Resource1()) {
r1.use();
} catch (Exception e) {
System.out.println("捕获的异常: " + e.getMessage());
Throwable[] suppressed = e.getSuppressed();
System.out.println("被抑制的异常数量: " + suppressed.length);
}
}
}6. 实际应用示例
文件操作示例
import java.io.*;
public class FileCopyExample {
public static void copyFile(String source, String dest) {
// 传统方式
/*
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(source);
fos = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) fis.close();
if (fos != null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
*/
// try-with-resources 方式
try (FileInputStream fis = new FileInputStream(source);
FileOutputStream fos = new FileOutputStream(dest)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}数据库连接示例
import java.sql.*;
public class DatabaseExample {
public static void queryDatabase() {
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
// 自动管理 Connection, Statement, ResultSet
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
while (rs.next()) {
System.out.println(rs.getString("username"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}8. Java 9 增强功能
Java 9 允许在 try-with-resources 中使用 effectively final 的变量:
public class Java9Example {
public static void main(String[] args) throws Exception {
// Java 9 之前
try (FileReader reader1 = new FileReader("file1.txt");
FileReader reader2 = new FileReader("file2.txt")) {
// 使用资源
}
// Java 9 及之后
FileReader reader1 = new FileReader("file1.txt");
FileReader reader2 = new FileReader("file2.txt");
// reader1 和 reader2 必须是 effectively final
try (reader1; reader2) {
// 使用资源
}
}
}9. 注意事项
- 资源类必须实现
AutoCloseable或Closeable接口 - 资源在 try 块结束后自动关闭,无论是否发生异常
- 多个资源按声明相反顺序关闭
- 如果有多个异常,只有第一个异常被抛出,其他异常被抑制
评论 (0)