Java7 的 try-with-resources 很棒,但我无法理解为什么需要在 try
语句中包含资源的声明。我的直觉说以下应该是可能的:
CloseableResource thing;
try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) {
// do some interesting things
}
thing.collectSomeStats();
唉,这会导致语法错误(神秘地期望;
)。将类型定义/声明移动到 try
语句中是有效的,这当然会将事物移动到相应的范围内。当我想从AutoClosable
那里得到比关闭更多的东西时,我可以弄清楚如何解决这个问题,我对为什么编译器需要这样感兴趣。
从 Java 9 开始,您可以在块外声明和初始化在 try-with-resources 中使用的变量。对变量的唯一附加要求是它必须是有效的最终的。
所以现在可以做到:
CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect();
try (thing) {
// do some interesting things
}
thing.collectSomeStats();
希望对您有所帮助。
您的版本没有明确定义应该关闭的内容,例如
CloseableResource thing;
Parameter a;
try (a = (thing = methodThatCreatesAThingAndDoesSomeSideEffect()).getParameter()) {
还有如果你写怎么办
try (12) {
还是什么?
也
CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect();
CloseableResource thing2 = methodThatCreatesAThingAndDoesSomeSideEffect();
try(thing1) {
}
为什么只关闭thing1
?
因此,当前的语法迫使您同时创建一个变量,并打开关闭块。
另外2
CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect();
try(thing1) {
}
thing1.doSomethingOnClosedResource();
因为thing1
仍然存在。
阅读 java 规范,我得出了这个结论(尽管它没有隐含地表明这一点):
它们让你声明变量并向其添加一个隐式 final,以确保你不能将变量重新绑定到其他东西。
在这种情况下,将无法关闭资源,因为它不再绑定到变量。
例如:
CloseableResource thing;
try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) {
thing = null;
// thing can't be closed now
}
如果我想它在外面,他们可以让你使用最终,但它有点丑陋。
解决方法:如果要访问声明的资源,可以使用finally
:
try (CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect()) {
// do some interesting things
} finally {
thing.collectSomeStats();
}
请记住,最终thing
已经关闭