Why does try-with-resource require a local variable?

Solution 1:

The link in the comment by @McDowell reveals the correct answer in a blog post comment by Joe Darcy who led the Java Technology Specification that introduced the try-with-resources statement:

Back in JDK 7, we started with a try-with-resources construct like that allowed a general expression to be used for the resource, including a method call. However, the expert group found by the early draft review (http://jcp.org/aboutJava/communityprocess/edr/jsr334/index.html) that

"A possible future change [to the try-with-resources statemenbt] is dropping support for a resource to be specified as a general Expression. Nontrivial specification and implementation complexities arise from allowing a general Expression to be used as resource. A restricted expression that could be an identifier or a PrimaryNoNewArray may suffice. Even the more severe restriction of just allowing an identifier may provide nearly all the additional utility of allowing a full expression (over forcing the declaration of a new resource variable) at a much lower marginal implementation and specification impact."

By the end of JDK 7, what we wanted was a fresh variable declaration for the resource or an existing final / effectively final variable. We only had time to provide the former in 7; in 9, we are providing the latter too.

Solution 2:

Among the use cases that they were considering, most would need to access the resource inside the block, for example, open file - read/write file - close file. They would not have made this design decision if they thought there are a lot of use cases where the local variable is unused.

As to why Lock isn't auto-closeable, I think Doug Lea isn't too concerned with syntax matter, he focuses on solving the hard problem. Others can always add syntax sugar on top of his utilities.

Looking forward, try-with-resource probably will fall out of fashion, replaced by lambda. For example

lock.withLock( ()->{ execute-while-holding-the-lock; } );

Solution 3:

As much as I wish it wasn't, the rationale behind it is that the try-with-resources is intended strictly for operations on the item that must be disposed of. It requires a named variable because it expects that you will do something with that variable while you're inside the block. I guess it's like the compiler saying "If you don't plan on actually using the resource, why are you doing a try-with-resources?"

Now you and I know full well that we don't want to actually use the resource: rather, we just want to make sure it's closed when we're done with it so we don't have devs going around locking up the system. But like so many things, they had to make design decisions and being in the minority, we didn't get the feature.