简体   繁体   中英

try-with-resources statement in Java

In this Java program example:

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...
    }
}

When, in the body of the static method example(), the OutOfMemoryError error is thrown, Are Connection "con" and Statement "stmt" automatically closed before terminating the static method example() despite there is not any "catch" that catches these error so in the rest of code in main() is sure that these two objects are closed ?

Thanks.

Yes; the try-with-resources construct always closes the resource, even if it's an unchecked throwable (like OutOfMemoryError).

This is specified in JLS 14.20.3 , which starts with a pretty generic statement that the resources are "closed automatically," but then goes into various examples of times when a resource is closed. Basically, any non- null resource is always closed, as if the close had been in the finally clause of a try-finally created just for that one resource. This is the case even if there are multiple resources in the try , as in your case ("An exception from the closing of one resource does not prevent the closing of other resources").

Simple class to demonstrate it:

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();
    }
  }
}

Output:

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

Note that they're closed in reverse order; "second" is closed before "first." In your example, this means that the Statement is closed before the Connection , which is exactly what you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM