在 Java 7 中,不应显式关闭它们,而应使用自动资源管理来确保关闭资源并正确处理异常。异常处理的工作方式如下:
Exception in try | Exception in close | Result
-----------------+--------------------+----------------------------------------
No | No | Continue normally
No | Yes | Throw the close() exception
Yes | No | Throw the exception from try block
Yes | Yes | Add close() exception to main exception
| | as "suppressed", throw main exception
希望这是有道理的。In 允许漂亮的代码,如下所示:
private void doEverythingInOneSillyMethod(String key)
throws MyAppException
{
try (Connection db = ds.getConnection()) {
db.setReadOnly(true);
...
try (PreparedStatement ps = db.prepareStatement(...)) {
ps.setString(1, key);
...
try (ResultSet rs = ps.executeQuery()) {
...
}
}
} catch (SQLException ex) {
throw new MyAppException("Query failed.", ex);
}
}
在 Java 7 之前,最好使用嵌套的最终块,而不是测试引用是否存在 null。
我将展示的示例在深度嵌套中可能看起来很丑陋,但在实践中,精心设计的代码可能不会以相同的方法创建连接,语句和结果;通常,每个级别的嵌套都涉及将资源传递给另一个方法,该方法将其用作另一个资源的工厂。使用此方法,来自 的异常将屏蔽来自块内部的异常。这是可以克服的,但它会导致更混乱的代码,并且需要一个自定义异常类来提供Java 7中存在的“抑制”异常链。close()
try
Connection db = ds.getConnection();
try {
PreparedStatement ps = ...;
try {
ResultSet rs = ...
try {
...
}
finally {
rs.close();
}
}
finally {
ps.close();
}
}
finally {
db.close();
}