为什么Java的try-with-resource需要声明

Java7的try-with-resources非常棒,但是我无法理解为什么需要在try语句中包含资源声明。 我的直觉说以下应该是可能的:

 CloseableResource thing; try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) { // do some interesting things } thing.collectSomeStats(); 

唉,这会导致语法错误(密码期待a ; )。 将类型定义/声明移动到try语句中,这当然会将事物移动到相应的范围中。 我可以弄清楚如何解决这个问题,当我想要更多来自我的AutoClosable不是关闭时,我很感兴趣为什么编译器需要它这样。

例如,您的版本没有明确定义应该关闭的内容

 CloseableResource thing; Parameter a; try (a = (thing = methodThatCreatesAThingAndDoesSomeSideEffect()).getParameter()) { 

如果你写的话该怎么办

 try (12) { 

或者其他的东西?

 CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect(); CloseableResource thing2 = methodThatCreatesAThingAndDoesSomeSideEffect(); try(thing1) { } 

为什么只关闭thing1

因此,当前语法强制您同时打开关闭块来创建变量。

ALSO2

CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect();

 try(thing1) { } thing1.doSomethingOnClosedResource(); 

因为thing1仍然存在。

阅读java规范我得出了这个结论(虽然它没有含蓄地表示如此):

它们使您声明变量并向其添加隐式final,以确保您无法将变量重新绑定到其他位置。

在这种情况下,将无法关闭资源,因为它不再绑定到变量。

例如:

 CloseableResource thing; try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) { thing = null; // thing can't be closed now } 

如果它在外面,我们可以让你使用final,但它有点难看。


解决方法:如果要访问声明的资源,可以使用finally

 try (CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect()) { // do some interesting things } finally { thing.collectSomeStats(); } 

请记住,最后thing已经关闭

Java 9开始,您可以声明并初始化块外的try-with-resources中使用的变量。 变量的唯一额外要求是它必须是有效的最终要求 。
所以现在可以这样做:

 CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect(); try (thing) { // do some interesting things } thing.collectSomeStats(); 

希望能帮助到你。