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

aka*_*IOT 14 java try-catch

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

CloseableResource thing;
try (thing = methodThatCreatesAThingAndDoesSomeSideEffect()) {
    // do some interesting things
}
thing.collectSomeStats();
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*zyk 10

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

CloseableResource thing = methodThatCreatesAThingAndDoesSomeSideEffect();
try (thing) {
    // do some interesting things
}
thing.collectSomeStats();
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。


Dim*_*ims 7

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

CloseableResource thing;
Parameter a;

try (a = (thing = methodThatCreatesAThingAndDoesSomeSideEffect()).getParameter()) {
Run Code Online (Sandbox Code Playgroud)

如果你写的话该怎么办

try (12) {
Run Code Online (Sandbox Code Playgroud)

或者其他的东西?

CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect();
CloseableResource thing2 = methodThatCreatesAThingAndDoesSomeSideEffect();

try(thing1) {
}
Run Code Online (Sandbox Code Playgroud)

为什么只关闭thing1

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

ALSO2

CloseableResource thing1 = methodThatCreatesAThingAndDoesSomeSideEffect();

try(thing1) {
}

thing1.doSomethingOnClosedResource();
Run Code Online (Sandbox Code Playgroud)

thing1遗骸.

  • **#1:**表达式可以被计算,它必须导致一些'AutoCloseable`实例,它将被关闭:在你的情况下`a`(和`thing`,它是对同一个东西的引用) .想想`if(布尔表达式)`,从来都不清楚,不管你在那个表达式中弄乱了多少个布尔值.**#2:**从语法上讲,```分隔符可以提供多个`AutoCloseable`表达式.**#3:**没有人阻止我做`try(CloseableResource alias = thing1){...}`然后`thing1`仍然在该块后面的范围内,所以这个防御是没用的. (2认同)