try-with-resources 解决了资源泄露、代码冗余和异常处理不优雅三大痛点,1. 它通过自动关闭实现 autocloseable 接口的资源,确保无论 try 块正常或异常结束,资源都会被可靠释放;2. 它将资源声明与使用集中在 try 括号内,消除了繁琐的 finally 块,使代码更简洁清晰;3. 当 try 块异常与 close() 异常同时发生时,close() 异常会被作为被抑制异常添加到主异常中,保留完整异常信息;4. 要使用该特性,资源类必须实现 autocloseable 接口并在 close() 方法中定义释放逻辑;5. 最佳实践中应直接在 try 括号内声明并初始化资源,仍需 catch 处理业务异常,并注意 close() 异常可能被抑制但可通过 getsuppressed() 获取,该特性仅适用于需显式关闭的资源,是现代 java 开发推荐的标准做法。
try-with-resources
AutoCloseable
finally
使用
try-with-resources
try
java.lang.AutoCloseable
try
比如,以前我们读文件,代码可能是这样的:
立即学习“Java免费学习笔记(深入)”;
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class OldWay { public static void main(String[] args) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader("example.txt")); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { System.err.println("读取文件时发生错误: " + e.getMessage()); } finally { if (reader != null) { try { reader.close(); } catch (IOException e) { System.err.println("关闭资源时发生错误: " + e.getMessage()); } } } } }
现在,有了
try-with-resources
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class NewWay { public static void main(String[] args) { try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { System.err.println("读取文件时发生错误: " + e.getMessage()); } } }
可以看到,那个冗长的
finally
try-with-resources
这玩意儿的出现,真的解决了我们开发者好几个心头大患。
首先是资源泄露的问题。以前写代码,最怕的就是资源忘了关,或者在异常路径下没关上,那真是噩梦。比如数据库连接、文件流、网络Socket,这些东西一旦没关,轻则拖慢系统,重则直接把服务器搞崩。手动管理
finally
close()
close()
try-with-resources
try
其次是代码的冗余。那些
try-finally
try-finally
try
再来就是异常处理的优雅。如果
try
close()
try-with-resources
close()
Throwable.getSuppressed()
AutoCloseable
要让一个资源能被
try-with-resources
java.lang.AutoCloseable
void close() throws Exception;
Java 标准库中很多类都实现了这个接口,比如各种
InputStream
OutputStream
Reader
Writer
java.sql
Connection
Statement
ResultSet
那如果我自己写了个类,它管理着一些需要在使用后释放的资源(比如一个自定义的网络连接池,或者一个需要关闭的本地资源句柄),怎么让它也能享受
try-with-resources
AutoCloseable
close()
class MyCustomResource implements AutoCloseable { private String name; public MyCustomResource(String name) { this.name = name; System.out.println(name + " 资源被打开了。"); } public void doSomething() { System.out.println(name + " 正在执行一些操作..."); // 模拟可能抛出异常的操作 // if (Math.random() > 0.5) { // throw new RuntimeException(name + " 操作失败了!"); // } } @Override public void close() throws Exception { System.out.println(name + " 资源被关闭了。"); // 模拟关闭时可能抛出异常 // if (Math.random() > 0.8) { // throw new IOException(name + " 关闭时发生错误!"); // } } } public class CustomResourceDemo { public static void main(String[] args) { try (MyCustomResource res1 = new MyCustomResource("资源A"); MyCustomResource res2 = new MyCustomResource("资源B")) { res1.doSomething(); res2.doSomething(); // 如果这里抛出异常,res1和res2依然会被关闭 } catch (Exception e) { System.err.println("捕获到异常: " + e.getMessage()); for (Throwable suppressed : e.getSuppressed()) { System.err.println("被抑制的异常: " + suppressed.getMessage()); } } } }
运行上面这段代码,你会看到无论
doSomething()
MyCustomResource
close()
AutoCloseable
try-with-resources
尽管
try-with-resources
一个常见的误区是,有人觉得它能解决所有资源管理问题。不,它只针对那些实现了
AutoCloseable
try-with-resources
关于最佳实践:
首先,资源的声明应该直接在
try
try
try-with-resources
// 错误示例:资源不会被自动关闭 BufferedReader reader; try (reader = new BufferedReader(new FileReader("example.txt"))) { // ... } catch (IOException e) { // ... } // reader在这里可能未被关闭
正确的做法是:
// 正确示例:资源会被自动关闭 try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) { // ... } catch (IOException e) { // ... }
其次,虽然
try-with-resources
catch
再者,如果
close()
close()
getSuppressed()
最后,一旦用上了
try-with-resources
finally
try-with-resources
以上就是java如何使用try-with-resources简化资源关闭 java资源关闭简化的实用教程操作的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号