15

In the try-with-resources construct of Java 7, I can declare a resource in the try statement, and it will be closed automatically when it goes out of scope.

However, I don't find any indication of the scope of the resource made available. Specifically, is it available in the catch/finally blocks of the try block where it is declared?

I tried the following in Eclipse Kepler, but it's giving a mixed impression:

Resource variable is made available by Content Assist (Code Completion):

Content Assist suggests resource

Quick Fix suggests changing to resource variable, but this recursively produces the same problem it's trying to fix:

Redundant suggestion in Quick Fix

I would like to know what the correct scope limitation is, before raising a bug in the Eclipse Bug Tracker.

4

4 回答 4

10

这种语法称为扩展的 try-with-resources

根据JLS

try ResourceSpecification
    Block
Catchesopt
Finallyopt

将被翻译成:

try {
    try ResourceSpecification
        Block
}
Catchesopt
Finallyopt

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

编辑:

我的问题没有嵌套的 try 块

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

于 2013-09-09T04:15:28.443 回答
7

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 块范围之外的资源。唯一的限制是 reader 变量应该是有效的 final 或只是 final。

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

于 2017-08-30T14:55:40.970 回答
4

除了@Nambari 的回答:

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

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

参考

于 2013-09-09T04:18:11.867 回答
4

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

JLS声明_

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

因此,从它在 ResourceSpecification(...)中声明的那一刻try起,直到.}try Block

TryWithResourcesStatement:
    try ResourceSpecification Block Catchesopt Finallyopt

ResourceSpecification:
    ( Resources ;opt )

Resources:
    Resource
    Resource ; Resources

Resource:
    VariableModifiersopt Type VariableDeclaratorId = Expression
于 2013-09-09T04:11:04.517 回答