在 Java 7 中,您不应该显式关闭它们,而是使用自动资源管理来确保关闭资源并正确处理异常。异常处理的工作方式如下:
尝试中的异常 | 关闭异常 | 结果
-----------------+--------------------+------------ -----------------------------------------
没有 | 没有 | 继续正常
没有 | 是 | 抛出 close() 异常
是 | 没有 | 从 try 块中抛出异常
是 | 是 | 将 close() 异常添加到主异常
| | 作为“抑制”,抛出主要异常
希望这是有道理的。在允许漂亮的代码,像这样:
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 之前,最好使用嵌套的 finally 块,而不是测试 null 的引用。
我将展示的示例使用深度嵌套可能看起来很难看,但在实践中,设计良好的代码可能不会以相同的方法创建连接、语句和结果;通常,每个级别的嵌套都涉及将资源传递给另一个方法,该方法将其用作另一个资源的工厂。使用这种方法,来自 a的异常将掩盖块close()
内部的异常。try
这是可以克服的,但它会导致代码更加混乱,并且需要一个自定义异常类来提供 Java 7 中存在的“被抑制的”异常链接。
Connection db = ds.getConnection();
try {
PreparedStatement ps = ...;
try {
ResultSet rs = ...
try {
...
}
finally {
rs.close();
}
}
finally {
ps.close();
}
}
finally {
db.close();
}