【问题标题】:Java try-finally inside try-catch patternJava try-finally 在 try-catch 模式中
【发布时间】:2011-11-17 23:51:11
【问题描述】:

每当我需要在 Java 中获取资源并保证资源被释放时,可能会引发异常,我使用以下模式:

try {
  Resource resource = null;
  try {
    resource = new Resource();
    // Use resource
  } finally {
    if (resource != null) {
      // release resource
    }
  }
} catch (Exception ex) {
  // handle exceptions thrown by the resource usage or closing
}

例如,如果我需要一个数据库连接,并且使用或关闭连接都会抛出异常,我编写如下代码:

try {
  Connection connection = null;
  try {
    connection = ... // Get database connection
    // Use connection -- may throw exceptions
  } finally {
    if (connection != null) {
      connection.close(); // This can also throw an exception
    }
  }
} catch (SQLException ex) {
  // handle exceptions thrown by the connection usage or closing
}

我不喜欢只做一个简单的 try-catch-finally,因为我有义务捕捉在数据库连接关闭时可能引发的(可能的)异常,而我从不知道如何处理那个异常。

有没有更好的模式来处理这种情况?

【问题讨论】:

  • 为什么不在正常异常中添加finally子句。(本例中为SqlException..)
  • 类似,但不完全是骗局:stackoverflow.com/questions/1335812/…
  • 我不喜欢在关闭资源之前必须检查资源是否为空。我宁愿在 try 块之外创建资源并避免所有这些。关闭期间抛出的异常也非常无用,只需记录它们并继续。

标签: java exception-handling


【解决方案1】:

如果您不知道如何处理异常,则不应捕获它们。

【讨论】:

    【解决方案2】:

    IOUtils.closeQuietly() 可以解决你的问题。

    例子:

        Closeable closeable = null;
        try {
            closeable = new BufferedReader(new FileReader("test.xml"));
            closeable.close();
        } catch (IOException e) {
            // Log the exception
            System.err.println("I/O error");
        } finally {
            // Don't care about exceptions here
            IOUtils.closeQuietly(closeable);
        }
    

    【讨论】:

    • 我看不出这里的closeable.close() 有什么意义,如果它已经被IOUtils.closeQuietly(closeable); 关闭了。此外,这正在吞噬异常。也许让它传播并在更高的层次上处理会更好。好吧,如果您不知道该怎么做,显然有两种选择。吞咽或传播:)
    • 我之前的例子是吞下异常。这是记录和吞咽。好多了 :)。谢谢@Xavi。
    • 哈哈,确实是的 :) 谢谢你也告诉我closeQuietly()
    【解决方案3】:

    就个人而言,我使用以下模式:

      Connection connection = null;
      try {
        connection = ... // Get database connection
        // Use connection -- may throw exceptions
      } finally {
        close(connection);
      }
    
    private void close(Connection connection) {
      try {
        if (connection != null) {
          connection.close(); // This can also throw an exception
        }
      } catch (Exception e) {
        // log something
        throw new RuntimeException(e); // or an application specific runtimeexception
      }
    }
    

    或类似的。这种模式不会丢失异常,但会使您的代码更清晰。当 finally 子句(在本例中为 close())中捕获的异常难以处理且应在更高级别处理时,我使用此模式。

    更干净的还是使用贷款模式。

    【讨论】:

      猜你喜欢
      • 2011-10-31
      • 2015-09-05
      • 2014-11-27
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 2011-02-20
      • 2019-02-28
      • 1970-01-01
      相关资源
      最近更新 更多