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

专业从事软件研发工作多年,在软件设计、开发、测试、研发管理等领域里经验丰富,感兴趣的朋友可以关注我的头条号,相信一定会有所收获。

如果有软件研发方面的问题,可以咨询我。

谢谢!


分享到:


相關文章: