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

◇◆丶佛笑我妖孽 提交于 2020-08-17 23:46:20

问题


With reference to my question Any risk in a AutoCloseable wrapper for java.util.concurrent.locks.Lock?, I am wondering why trh try-with-resource require a named local variable at all.

My current usage is as follows:

try (AutoCloseableReentrantReadWiteLock.Lock l = _lock.writeLock()) {
    // do something
}        

The variable l is unused inside the try block and only pollutes the namespace. From what I can remember the analogous C# using statement does not require a local named variable.

Is there any reason the following could not have been supported, with an anonymous local variable that is closed at the end of try block?

try (_lock.writeLock()) {
    // do something
}        

回答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.




回答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; } );



回答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.




回答4:


I think that inability to use local variable was the trigger for try-with-resource.

Prior to java 1.7 you had to write something like this:

InputStream in = null;
try {
    in = ....;
} finally {
    if (in != null) {
        in.close();
    }
}

There are 2 disadvantages here:

  1. finally block is annoying and have to be null-safe for each closing resource
  2. We must declare resources outside the block just be able to access them in finally block. Therefore we enlarge the scope where the variables are accessible that is bad practice.

Try-with-resource syntax solves both problems:

  1. finally block is not needed at all.
  2. The resource variable remains accessible into try block only, i.e. where it should be known.

This is why the closable resource must be local. Otherwise one of the main disadvantages of try-with-resource syntax is "disabled".



来源:https://stackoverflow.com/questions/16588843/why-does-try-with-resource-require-a-local-variable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!