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?
The try -with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try -with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.
For try-with-resources, if an exception is thrown in a try block and in a try-with-resources statement, then the method returns the exception thrown in the try block. The exceptions thrown by try-with-resources are suppressed, i.e. we can say that try-with-resources block throws suppressed exceptions.
In the try-with-resources method, there is no use of the finally block. The file resource is opened in try block inside small brackets. Only the objects of those classes can be opened within the block which implements the AutoCloseable interface, and those objects should also be local.
A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
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 final Some obj = new Some(); try (obj) { // obj captured in a hidden local variable, resource closed in the end }
I suspect the designers considered using a field a bad idea as this allow the object to escape the region of usage. i.e. it is only valid in the try block so you shouldn't be able to access it anywhere else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With