【发布时间】:2011-08-12 13:31:48
【问题描述】:
当我清理一些代码时,FindBugs 向我指出了一些使用 Connection、CallableStatement 和 ResultSet 对象的 JDBC 代码。这是该代码中的一个 sn-p:
CallableStatement cStmt = getConnection().prepareCall("...");
...
ResultSet rs = cStmt.executeQuery();
while ( rs.next() )
{
...
}
cStmt.close();
rs.close();
con.close();
FindBugs 指出这些应该在 finally 块中。我开始重构我的代码来做到这一点,我开始想知道如何处理 finally 块中的代码。
创建 Connection 对象的 CallableStatement 可能会引发异常,使我的 ResultSet 对象为空。当我尝试关闭 ResultSet 时,我会收到 NullPointerException,而我的 Connection 将永远不会关闭。事实上,this thread 提出了相同的概念,并表明将您的 close() 调用包装在一个空检查中是一个好主意。
但是其他可能的例外情况呢?根据 Java API 规范,Statement.close() 可以“如果发生数据库错误”抛出 SQLException。因此,即使我的 CallableStatement 不为 null 并且我可以成功地对其调用 close(),我仍然可能会遇到异常并且没有机会关闭我的其他资源。
我能想到的唯一“故障安全”解决方案是将每个 close() 调用包装在其自己的 try/catch 块中,如下所示:
finally {
try {
cStmt.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
try {
rs.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
try {
con.close();
} catch (Exception e) { /* Intentionally Swallow Exception */ }
}
男孩,如果这看起来不可怕的话。有没有更好的方法来解决这个问题?
【问题讨论】:
-
吞咽异常可能是你能做的最糟糕的事情,s。我的回答。