196. Java 异常 - Try-with-Resources:自动关资源的神器!
🧠 什么是 try-with-resources?
在 Java 中,有些对象用完之后必须关闭,比如:文件、数据库连接、网络流等。这些对象被称为 资源(resources)。
Java 7 起,提供了一个新语法叫:
🔧
try-with-resources:自动关闭资源的try块
相比以前写 try-finally 手动关闭资源的方式,它更简洁、更安全。
✅ 用法一览
try (ResourceType name = new ResourceType()) {
// 使用资源
} catch (...) {
// 异常处理
} finally {
// 可选的收尾
}
- ✅ 所有资源在
}之后自动关闭 - ✅ 顺序是:先声明的后关闭
- ✅ 所有资源类型必须实现
AutoCloseable接口(比如Closeable)
💡 例子:读取文件的第一行
🔎 Java 7+ 推荐写法:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
👍 没有 finally,代码清爽,BufferedReader 会被自动关闭!
⛔Java 7前的传统写法:
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
⚠️ 如果 readLine() 和 close() 都抛异常,只有 finally 中的异常会被抛出,前面的异常会被“吃掉”!
🔁 多个资源怎么办?
你可以在 try 中声明多个资源,用 ; 分隔:
try (
ZipFile zf = new ZipFile(zipFileName);
BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset)
) {
for (Enumeration<? extends ZipEntry> entries = zf.entries(); entries.hasMoreElements();) {
String entryName = entries.nextElement().getName() + System.lineSeparator();
writer.write(entryName);
}
}
🧹 退出 try 块后,writer 和 zf 都会被自动关闭!而且是先关闭 writer,后关闭 zf(后创建的先关闭)。
☕ 示例:数据库查询也能用!
public static void viewTable(Connection con) throws SQLException {
String query = "SELECT COF_NAME, SUP_ID, PRICE, SALES, TOTAL FROM COFFEES";
try (Statement stmt = con.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
System.out.println(
rs.getString("COF_NAME") + ", " +
rs.getInt("SUP_ID") + ", " +
rs.getFloat("PRICE") + ", " +
rs.getInt("SALES") + ", " +
rs.getInt("TOTAL")
);
}
} catch (SQLException e) {
e.printStackTrace(); // 实际项目中建议写日志或提示用户
}
}
📌 这个例子用 try-with-resources 自动关闭 JDBC 的 Statement 对象,干净利落!
🧩 实用贴士
| 提示 | 内容 |
|---|---|
| ✅ 推荐使用 | 所有实现了 AutoCloseable 的资源都应该用这个语法 |
| 🚫 不可变 | try 中声明的变量是隐式 final,不能再赋值 |
| 📌 可选 finally | 可以同时加上 catch 或 finally,逻辑更完整 |
| 🧼 清洁顺序 | 最后创建的资源会最先关闭(类似栈结构) |
| ❗ 兼容性要求 | 只能在 Java 7 及以上使用 |
- “你再也不用担心忘了关文件了,Java 自动帮你清理!”
- “try-with-resources 是写 IO、数据库访问时的标配姿势。”
- “多个资源按顺序声明,Java 会自动逆序关闭它们,非常优雅。”
- “finally 中的异常可能覆盖真实错误,但 try-with-resources 会保留更多上下文!”
📌 总结:为什么用 try-with-resources?
| 优点 | 描述 |
|---|---|
| 🔒 安全 | 自动释放资源,防止泄漏 |
| 🧼 简洁 | 不需要手写 finally,代码更清晰 |
| 🤝 灵活 | 支持多个资源,支持 catch/finally |
| 🚫 少错 | 更容易写出正确的关闭逻辑 |