Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 649
ConcurrentHashMap Avatar asked Jun 21 '13 12:06

ConcurrentHashMap


People also ask

Can you explain about try-with-resources?

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.

How to handle exception in try-with-resources?

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.

How try-with-resources works internally?

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.

Does try-with-resources need a catch?

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.


2 Answers

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 } 
like image 98
Marko Topolnik Avatar answered Oct 22 '22 06:10

Marko Topolnik


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.

like image 28
Peter Lawrey Avatar answered Oct 22 '22 07:10

Peter Lawrey