尝试资源的资源范围

Java 7try -with-resources构造中,我可以在try语句中声明一个资源,当它超出范围时它将自动关闭。

但是,我没有发现任何可用资源范围的迹象。 具体来说,是否可以在try块的catch / finally块中声明它?

我在Eclipse Kepler中尝试了以下内容,但它给人的印象是:

资源变量由内容辅助(代码完成)提供

内容辅助建议资源

快速修复建议更改为资源变量,但这会递归地产生它尝试修复的相同问题:

快速修复中的冗余建议

在提出Eclipse Bug Tracker中的错误之前,我想知道正确的范围限制是什么。

此语法称为Extended try-with-resources

根据JLS :

 try ResourceSpecification Block Catchesopt Finallyopt 

将被翻译为:

 try { try ResourceSpecification Block } Catchesopt Finallyopt 

因此,在您的示例中,您的资源将仅限于内部try块,因此不适用于外部try/catch/finally

编辑:

我的问题没有嵌套的try块

通过在代码中显式添加catch / finally块,您将引入嵌套的try块。

正确的范围限制在声明部分(...)和实际的try块中。

JLS表示

在try-with-resources语句(第14.20.3节)的ResourceSpecification中声明的变量的范围来自于ResourceSpecification的其余部分以及与try-with-resources语句关联的整个try块的右侧声明。

因此,从try anwards的ResourceSpecification (...)中声明它直到try Block的最终结束}括号。

 TryWithResourcesStatement: try ResourceSpecification Block Catchesopt Finallyopt ResourceSpecification: ( Resources ;opt ) Resources: Resource Resource ; Resources Resource: VariableModifiersopt Type VariableDeclaratorId = Expression 

除了@ Nambari的回答:

try-with-resources语句可以像普通的try语句一样有catch和finally块。 在try-with-resources语句中,在声明的资源关闭后运行任何catch或finally块。

这几乎解释了行为,您的资源超出了显式catch / finally块的范围。

参考

Java 9发布后,2017年更新

现在使用Java 9我们有更多的语法糖,我们可以在try-catch块之外声明一个资源,但仍然可以正确处理。 这就是为什么在Java 9中,Try-With-Resources得到了改进,引入了一种新的语法:

 InputStream stream = new MyInputStream(...) try (stream) { // do something with stream being sure that is going to be closed at the end } catch(IOException e) { // you can surely use your resource here } 

请注意,此语法将导致Java版本8或次要版本的编译时错误

这是更“自然”的写作方式,即使在大多数用例中我们不需要try块范围之外的资源。 唯一的限制是读者变量应该是最终的或者最终的。

无论如何,使用这种语法,你肯定可以在catchfinally块中使用你的资源