当前位置: 首页 > 面试题库 >

如何正确关闭资源

堵乐
2023-03-14
问题内容

在清理一些代码时,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将永远不会关闭。确实,该线程提出了相同的概念,并表明将您的close()调用包装在空检查中是一个好主意。

但是其他可能的例外呢?根据JavaAPI规范,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 */ }

}

男孩,如果那看起来并不可怕。有更好的方法来解决这个问题吗?


问题答案:

我认为最好的答案已经被提及,但我想提到您可以考虑自动关闭资源的新JDK 7功能可能会很有趣。

try{
    try(Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/hrdb", "obiwan", "kenobi"); 
        Statement stm = conn.createStatement(); 
        ResultSet rs = stm.executeQuery("select name from department")) {

        while(rs.next()){
            System.out.println(rs.getString("name"));
        }

    } 
}catch(SQLException e){
    //you might wanna check e.getSuppressed() as well
    //log, wrap, rethrow as desired.
}

并不是我们所有人现在都可以迁移到JDK7,但是对于那些可以开始使用开发人员预览版的人来说,这提供了一种有趣的方式,并且肯定会在不久的将来弃用其他方法。



 类似资料:
  • 问题内容: 我有全部传播异常的方法,然后在一个地方处理,但是我意识到了一些事情。 假设我有这样的方法 我的问题是,如果doSometing()方法引发异常,该语句将不会关闭,但我不想在那里处理异常。尝试并捕获只会抛出异常并最终关闭语句的正确方法吗? 问题答案:

  • 问题内容: 其中哪一个是正确的? 问题答案: 工作正常,并正确关闭标签。最好为视障人士添加属性。

  • 问题内容: 如何正确关闭IPython Notebook? 目前,我只是关闭浏览器选项卡,然后在终端中使用。 不幸的是,滴答也无济于事(它们确实杀死了它们的内核,但没有退出iPython)。 问题答案: 当前没有比终端中的Ctrl + C更好的方法了。 我们正在考虑如何进行显式关机,但是笔记本作为单用户应用程序(用户可以自由停止它)和作为多用户服务器(只能由管理员操作)之间存在一些紧张关系。阻止它

  • 我有一个简单的java,它运行一些任务对象(实现)。 除了尽最大努力尝试停止处理正在执行的任务之外,没有任何保证。例如,典型的实现将通过{@link thread#interrupt}取消,因此任何未能响应中断的任务都可能永远不会终止。 我的问题是,有没有办法确保那些(任务)线程会终止?我想出的最佳解决方案是在程序末尾调用,但这显然是愚蠢的。

  • 我有一些代码,其中多个方法使用键盘,并在主方法中连续调用。我正在做的练习特别要求使用4种不同的方法,所以我不能把它们放在一起。最初,我用键盘。在每个方法的末尾关闭(),但当第二个方法运行时,无论调用顺序如何,这都会导致NoTouchElementException。通过卸下键盘。close(),代码现在可以工作了,但是我现在收到了资源泄漏的警告,因为键盘没有关闭。有人能告诉我一种关闭输入而不出错的

  • 问题内容: 我想在Java中实现SSL代理。我基本上打开了两个套接字,并运行了两个线程,这些线程将写入他们从中读取的内容,反之亦然。每个线程如下所示: 每个线程只会关闭输入套接字,因此最终两个套接字都会关闭。 但是,如果我想使用an 怎么办?似乎那里不支持这些方法。这是我得到的例外。 我想出的是: 每当套接字结束时,我都必须捕获并忽略套接字末尾异常。 我的问题是: 如果不受支持,我怎么会从那里得到