Effective Java代碼規則之九:try-with-resources優於try-finally

1、解釋

Java類庫中包括許多必須通過調用close方法來手工關閉的資源。例如InputStream、OutputStream和java.sql.Connection。客戶端經常會忽略資源的關閉,造成嚴重的性能後果。

在JDK1.7之前,close要放在finally中:

 ResultSet rs = null;
Connection con = null;
Statement stmt = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "system", "oracle");
stmt = con.createStatement();
rs = stmt.executeQuery("select * from emp");
while (rs.next())
System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3));
con.close(); // 如果上面代碼拋出異常是執行不到這裡的
} catch (Exception e) {
System.out.println(e);
} finally {
try {
if (rs != null)
rs.close();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
try {
if (stmt != null)
stmt.close();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
try {
if (con != null)
con.close();
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
}

寫法很複雜,1.7以後有了更好的方法:

 try (Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "system", "oracle");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from emp")) {
while (rs.next())
System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3));

} catch (SQLException e) {
throw new RuntimeException(e.getMessage());
}

2、優點

代碼變得更簡潔易懂, 也更容易進行診斷。

3、缺點

只有實現AutoCloseable或Closeable接口的資源才能使用該方法。

4、最佳實踐

在實際工作中,為了確保 try-with-resources 生效,要讓各個資源聲明獨立變量:

// 下面的代碼如果從文件(someFile.bin)創建ObjectInputStream時出錯,
// FileInputStream 可能就無法正確關閉。
try(ObjectInputStream in = new ObjectInputStream(new FileInputStream("someFile.in"))) {
...
}
//要確保 try-with-resources 生效,正確的用法是為了各個資源聲明獨立變量。
try(FileInputStream fin = new FileInputStream("someFile.bin");
ObjectInputStream in = new ObjectInputStream(fin)) {
...
}
Effective Java代碼規則之九:try-with-resources優於try-finally

專業從事軟件研發工作多年,在軟件設計、開發、測試、研發管理等領域裡經驗豐富,感興趣的朋友可以關注我的頭條號,相信一定會有所收穫。

如果有軟件研發方面的問題,可以諮詢我。

謝謝!


分享到:


相關文章: