为什么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();
希望能帮助到你。