Java7的try-with-resources非常棒,但我无法理解为什么需要在try
语句中包含资源声明。我的直觉说以下应该是可能的:
CloseableResource thing;
try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) {
// do some interesting things
}
thing.collectSomeStats();
唉,这会导致语法错误(隐藏地期望;
)。将类型定义/声明移动到try
语句中会起作用,这当然会将事物移动到相应的范围中。我想知道如何解决这个问题,当我想要更多来自AutoClosable
而不是关闭时,我对为什么编译器需要它感兴趣。
答案 0 :(得分:7)
您的版本未明确定义应关闭的内容,例如
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
仍然存在。
答案 1 :(得分:4)
从 Java 9 开始,您可以声明并初始化块外的 try-with-resources 中使用的变量。变量的唯一额外要求是它必须是effectively final 所以现在可以这样做:
CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect();
try (thing) {
// do some interesting things
}
thing.collectSomeStats();
希望它有所帮助。
答案 2 :(得分:2)
阅读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
已经关闭