尝试使用资源,如果未捕获引发的异常,资源是否干净?

Cof*_*ups 3 java java-8

当try-with-resource引发一个外部捕获的异常时,会发生什么?还会进行清理吗?

样品:

public void myClass() throws customException {
  try (Connection conn = myUtil.obtainConnection()) {
     doSomeStuff(conn);
     if (someCheck)
       throw new customException(somePara);

     doSomeMoreStuff(conn);
     conn.commit();

  } catch (SQLException e) {
     log.error(e);
  }
}
Run Code Online (Sandbox Code Playgroud)

我关心的部分是何时抛出customException。我没有用try-with-resource捕获此异常。因此,我想知道在这种情况下是否将执行连接清理。

还是我需要捕获并重新抛出连接,如下所示:

public void myClass() throws customException {
  try (Connection conn = myUtil.obtainConnection()) {
     doSomeStuff(conn);
     if (someCheck)
       throw new customException(somePara);

     doSomeMoreStuff(conn);
     conn.commit();

  } catch (SQLException e) {
     log.error(e);
  } catch (customException e) {
     throw new customException(e);
  }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

文档可以回答您的确切问题

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

如果从 try 块抛出异常,并且 try-with-resources 语句抛出一个或多个异常,那么这些从 try-with-resources 语句抛出的异常将被抑制,并且块抛出的异常是由 writeToFileZipFileContents 方法抛出。您可以通过从 try 块抛出的异常中调用 Throwable.getSuppressed 方法来检索这些被抑制的异常。

请查看https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html


Oli*_*ire 5

是的,将发生清理...如果该close()方法正确处理了清理:

执行示例

public class Main {
  public static void main(String[] args) throws Exception {
    try (AutoCloseable c = () -> System.out.println("close() called")) {
      throw new Exception("Usual failure");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

(由Holger在评论中缩短)

在标准输出上输出:

close() called
Run Code Online (Sandbox Code Playgroud)

在stderr上的输出:

Exception in thread "main" java.lang.Exception: Usual failure
    at Main.main(Main.java:4)
Run Code Online (Sandbox Code Playgroud)

close()方法中引发异常的执行示例

(由Holger建议在评论中)

public class Main {
  public static void main(String[] args) throws Exception {
    try (AutoCloseable c = () -> { throw new Exception("Failure in the close method"); }) {
      throw new Exception("Usual failure");
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

标准输出无输出。

在stderr上的输出:

Exception in thread "main" java.lang.Exception: Usual failure
    at Main.main(Main.java:4)
    Suppressed: java.lang.Exception: Failure in the close method
        at Main.lambda$main$0(Main.java:3)
        at Main.main(Main.java:3)
Run Code Online (Sandbox Code Playgroud)