首页 > 解决方案 > Java - 如果发生异常,连接/流是否已经关闭以及如何正确处理?

问题描述

我想知道,如果我的代码中有某种连接或流应该关闭以释放资源,这对连接实例本身意味着什么?

代码示例:

CustomConnection connection;
try{
    connection = //some code that opens a connection
    //some code using the connection
}catch(IOException){
    //Some logging and Handling of IOExceptions
}finally{
    //resources cleanup
    try{
        connection.close();
    }catch(IOException){
        //Some Logging
        //What else should be done here?
        //Is my Connection closed at this point and can I just move on?
        //Or should there be anything else done here 
        //to ensure that the connection is actually closed?
    }
}

例如,如果我有一个打开的 TCP 连接,假设是一个 SQL 服务器,但我无法关闭它,因为服务器已崩溃或我的设备无法再访问该设备。我显然会得到一个 IO,或者在这种情况下是一个 SQLException。如果是这样:

  1. 我应该考虑资源或套接字实际上已经释放了 benn 吗?
  2. JVM 或操作系统会超时处理它吗?(操作系统最终可能会这样做,但在这种情况下实际上是一种好的编程实践)
  3. 我应该通过尝试自己处理这个问题吗

编辑1:我知道“尝试资源”结构。我只是想知道如果我使用的连接没有实现 AutoCloseable,如何处理连接关闭。

标签: javaexception-handlingconnectioninputstreamioexception

解决方案


我将CustomConnection实现该AutoClosable接口,以便它可以在 try-with-resources 语句中使用:

try (CustomConnection connection = ...) {

} catch (IOException e) {
    // connection is not in scope here, and it is closed.
}

从 Oracle 的 try-with-resources教程中,它指出:

注意:try-with-resources 语句可以像普通的 try 语句一样有 catch 和 finally 块。在 try-with-resources 语句中,任何 catch 或 finally 块都会在声明的资源关闭后运行。

使用它来回答您的问题,您的资源将在输入 acatchfinally块时关闭。


如果初始化连接会引发异常,则必须注意被抑制的异常:

可以从与 try-with-resources 语句关联的代码块中引发异常。在示例 writeToFileZipFileContents 中,可以从 try 块中引发异常,并且当 try-with-resources 语句尝试关闭 ZipFile 和 BufferedWriter 对象时,最多可以引发两个异常。如果从 try 块中抛出异常,并且从 try-with-resources 语句中抛出一个或多个异常,则从 try-with-resources 语句中抛出的那些异常被抑制,并且块抛出的异常就是那个由 writeToFileZipFileContents 方法抛出。您可以通过从 try 块抛出的异常调用 Throwable.getSuppressed 方法来检索这些抑制的异常。


推荐阅读