1. 背景
在 Java 開發中,很多資源(數據庫連接、ZooKeeper 連接、Redis 客戶端、文件流等)都需要手動關閉。如果忘記關閉,會導致 資源泄漏(連接占滿、內存泄漏、文件句柄耗盡等)。
為了避免這種問題,Java 提供了兩種方式來管理資源關閉:
傳統
try-finally
(Java 7 之前)
try-with-resources
(Java 7+ 引入,推薦 ?)
2. 傳統 try-finally 寫法
Connection conn = null; try {conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");// 使用連接System.out.println("連接成功!"); } catch (SQLException e) {e.printStackTrace(); } finally {if (conn != null) {try {conn.close(); // 手動關閉} catch (SQLException e) {e.printStackTrace();}} }
特點
必須在
finally
中手動關閉資源。代碼冗余,容易忘記寫。
多個資源時,
finally
代碼會很長。
3. Java 7+ try-with-resources 寫法(推薦)
只要資源類實現了
AutoCloseable
或Closeable
接口,就能在try
中創建,Java 會在執行完try
后自動關閉資源。try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456")) {// 使用連接System.out.println("連接成功!"); } catch (SQLException e) {e.printStackTrace(); } // 這里不需要寫 finally,conn 會自動關閉
特點
簡潔,少寫很多
finally
。更安全,不會忘記關閉資源。
支持多個資源同時管理:
try (InputStream in = new FileInputStream("a.txt");OutputStream out = new FileOutputStream("b.txt")) {// 同時使用 in 和 out }
4. 常見應用場景
(1)數據庫連接
try (Connection conn = DriverManager.getConnection(url, user, pass)) {// 執行 SQL }
(2)ZooKeeper(Curator)
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); try (CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", 60000, 15000, retryPolicy)) {client.start();// ZooKeeper 操作 }
(3)Redis(Jedis)
try (Jedis jedis = new Jedis("localhost", 6379)) {jedis.set("key", "value"); }
(4)文件流
try (FileInputStream fis = new FileInputStream("a.txt")) {int data;while ((data = fis.read()) != -1) {System.out.print((char) data);} }
5. 總結對比
寫法 關閉方式 代碼量 出錯風險 try-finally 手動關閉 冗余多 容易忘記關閉 try-with-resources 自動關閉(需實現 AutoCloseable
)簡潔 安全,推薦 ?
? 結論:
如果用的是 Java 7 及以上版本,強烈推薦使用 try-with-resources。
這種寫法常用于 數據庫、ZooKeeper、Redis、IO 流 等需要關閉的資源管理。