Why doesn't try-with-resources work with field variables?

ConcurrentHashMap picture ConcurrentHashMap · Jun 21, 2013 · Viewed 9.1k times · Source

This is my very first question on SO and I'm confused there isn't a similar question yet!

So the question is:

Why doesn't try-with-resources work with field variables?

Or in other words: Why do I always need a local variable for that?

Here goes some example code:

public class FileWriteTest {

    public FileWriter file;

    public void workingDemo() {

        try(FileWriter file = new FileWriter(new File("someFilePath")) {
            // do something
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void notWorkingDemo() {

        file = null;

        try(file = new FileWriter(new File("someFilePath")) {
            // do something
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

}

May anyone explain me why there is this convention?

Answer

Marko Topolnik picture Marko Topolnik · Jun 21, 2013

An instance variable may be changed at any point during the execution of the try-with-resources block. This would break its invariant and prevent the cleanup. Note that the local variable is implictly final, for the same reason.

BTW a better question is, why does Java force us to declare a local variable, even if we don't refer to it within the block. C#, for example, doesn't require this.

Update: with version 9, Java has stopped forcing us:

private Some obj = new Some();

try (obj) { 
  // obj captured in a hidden local variable, resource closed in the end
}