Java中的try-with-resources语句

时间:2014-05-16 18:11:53

标签: java try-with-resources

在这个Java程序示例中:

package test;

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Statement;

public class Test
{
    private static void example(){
        String url = "jdbc:oracle:thin:@//localhost:7856/xe";
        String user = "user";
        String password = "pass";
        try(Connection con = DriverManager.getConnection(url, user, password);
            Statement stmt = con.createStatement()){
            throw new OutOfMemoryError("Error");
        }catch (SQLException e){
            System.err.println("SQLException");
        }
    }

    public static void main(String [] args){
        try{
            example();
        }catch (OutOfMemoryError e){
            System.err.println("OutOfMemoryError");
        }
        // Rest of code here...
    }
}

当在静态方法example()的主体中抛出OutOfMemoryError错误时,是否连接" con"和声明" stmt"尽管没有任何" catch"捕获这些错误所以在main()的其余代码中确保这两个对象是关闭的吗?

感谢。

1 个答案:

答案 0 :(得分:5)

是; try-with-resources构造总是关闭资源,即使它是一个未经检查的throwable(如OutOfMemoryError)。

这在JLS 14.20.3中指定,它以一个非常通用的声明开头,即资源自动关闭,"但随后进入资源关闭的各种时间示例。基本上,任何非null资源都始终关闭,就像关闭已经在为该资源创建的finally try-finally子句中一样。即使try中存在多个资源,也就是这种情况("关闭一个资源的例外情况不会阻止关闭其他资源")。

简单的类来演示它:

public class Twr {
  private static class TwrCloseable implements AutoCloseable {
    private final String id;

    TwrCloseable(String id) {
      this.id = id;
    }

    @Override
    public void close() {
      System.out.println("closing " + id);
    }
  }

  public static void main(String[] args) {
    try (TwrCloseable closeable1 = new TwrCloseable("first");
         TwrCloseable closeable2 = new TwrCloseable("second")) {
      throw new OutOfMemoryError();
    }
  }
}

输出:

closing second
closing first
Exception in thread "main" java.lang.OutOfMemoryError
    at Twr.main(Twr.java:19)

请注意,它们会以相反的顺序关闭; "第二"在"之前关闭。"在您的示例中,这意味着StatementConnection之前关闭,这正是您想要的。