javatry-with-resources

Use resource in try with resource statement that was created before


Since Java 7, we can use try with resources:

try (One one = new One(); Two two = new Two()) {
    System.out.println("try");
} catch (Exception ex) { ... }

Now my question is, why do I have to create the object in the try-statement? Why am I not allowed to create the object before the statement like this:

One one = new One();
try (one; Two two = new Two()) {
    System.out.println("try");
} catch (Exception ex) { ... }

I don't see any reasons, why this should be a problem. Though I get the error message "Resource references are not supported at this language level". I set my IDE (IntelliJ IDEA) to Java 8, so that should work. Is there a good reason for this, being not allowed?


Solution

  • You don't have to create the object in the try-with-resources statement, you just have to declare some local variables of a type that implements AutoCloseable. The variables are effectively final, and scoped to the try block, which allows the compiler to use them to generate the close boilerplate needed for cleanup.

    FileInputStream f1 = new FileInputStream("test1.xml");
    FileInputStream f2 = new FileInputStream("test2.xml");
    // Don't need to create the resources here, just need to declare some vars
    try (InputStream in1 = f1; InputStream in2 = f2) {
        // error; in1 is final
        in1 = new FileInputStream("t");
    }
    

    Better Resource Management with Java SE 7: Beyond Syntactic Sugar.

    Addendum: Since java 9 the requirements have been relaxed; you don't have to redeclare the variables in the try block if the originals are effectively final.

    JEP 213