在 Java 7 的 try
- with-resources 构造中,我可以在try
语句中声明一个资源,它将会当它超出范围时自动关闭。
但是,我没有发现任何可用的资源范围的迹象。具体来说,它是在try块的catch
/ finally
块中可用的吗?
我在 Eclipse Kepler 中尝试了以下内容,但它给人的印象是:
资源变量由内容辅助(代码完成)提供:
快速修复建议更改为资源变量,但这会递归产生它尝试修复的同一问题:
我想在 Eclipse Bug Tracker 中引发错误之前知道正确的范围限制是什么。
答案 0 :(得分:8)
此语法称为 扩展试用资源
根据JLS:
try ResourceSpecification
Block
Catchesopt
Finallyopt
将被翻译为:
try {
try ResourceSpecification
Block
}
Catchesopt
Finallyopt
因此,在您的示例中,您的资源将仅限于内部try块,因此不适用于外部try/catch/finally
。
修改强>
我的问题没有嵌套的尝试块
通过在代码中显式添加catch / finally块,您将引入嵌套的try块。
答案 1 :(得分:4)
现在使用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块范围之外的资源。 唯一的限制是读者变量应该是有效的最终或最终。
无论如何,使用此语法,您确实可以在catch
和finally
块中使用您的资源
答案 2 :(得分:3)
正确的范围限制在声明部分(...)
和实际try
块内。
JLS州
在一个的ResourceSpecification中声明的变量的范围 try-with-resources语句(§14.20.3)来自声明 向右转过ResourceSpecification的剩余部分和 与try-with-resources语句关联的整个try块。
因此,从(...)
开始,在try
}
的最后结束try
括号之前,它会在{S(1}}}的ResourceSpecification Block
中声明。< / p>
TryWithResourcesStatement:
try ResourceSpecification Block Catchesopt Finallyopt
ResourceSpecification:
( Resources ;opt )
Resources:
Resource
Resource ; Resources
Resource:
VariableModifiersopt Type VariableDeclaratorId = Expression
答案 3 :(得分:3)
除了@ Nambari的回答:
try-with-resources语句可以捕获并最终阻塞 像一个普通的尝试声明。在try-with-resources语句中,任何 在声明的资源之后运行catch或finally块 闭合。
这几乎解释了行为,你的资源超出了显式catch / finally块的范围。