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



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已经关闭

最新更新