当我正在清理一些代码时,FindBugs指出了一些使用Connection,CallableStatement和ResultSet对象的JDBC代码.以下是该代码的片段:
CallableStatement cStmt = getConnection().prepareCall("...");
...
ResultSet rs = cStmt.executeQuery();
while ( rs.next() )
{
...
}
cStmt.close();
rs.close();
con.close();
FindBugs指出这些应该在一个finally块内.我开始重构我的代码来做到这一点,我开始想知道如何处理finally块中的代码.
可能的是创建Connection对象的CallableStatement会抛出异常,将我的ResultSet对象设置为null.当我尝试关闭ResultSet时,我会得到一个NullPointerException,而我的Connection会依次关闭.事实上,this thread提出了相同的概念,并表明在null检查中封装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 */ }
}
男孩,如果不看起来不好看.有没有更好的方法来解决这个问题?