Use resource in try with resource statement that was created before

It is actually possible:

One one = new One();
try (One temp = one; ....;) {

}

and starting with Java 9 you don't even need to declare an additional variable, and instead you can use the variable directly:

One one = new One();
try (one) {
    //...
}

However there is almost never a good reason to create the resource before the try-with-resources. This was probably the reason the try-with-resources block originally required you to declare a new variable in the resource-list (which also easily enforces that the variable is final). However, the language designers decided that flexibility was more important here.

Creating the resource before the try-with-resources block could lead to subtle bugs because the resource is not properly closed if an exception happens before you enter the block (eg if you do other things between creating a One and entering the try-with-resources block).

And generally you should have no reason for accessing a resource after it has been closed, so you should limit the scope to the time the resource is open (ie the try-with-resources block). If you do need to access a resource after it has been closed, you may need to consider a different design, where the (closable) resource is separated from the object/data you need after closing the resource, or you need to use nested try-with-resources blocks.

An exception to this, might be if you get an AutoCloseable passed in, and your method must guarantee it is closed on exit, but this is generally a design smell though: the one opening a resource should also be responsible for closing it.


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