每当需要与语言相关的细节时,最完整的参考就是Java语言规范(仅适用于Google)。对于
try-with-
resources语句,您可以阅读14.20.3节,其中指出以下内容:
try ({VariableModifier} R Identifier = expression ...) Block被翻译成
{ final {VariableModifierNoFinal} R Identifier = expression; Throwable #primaryExc = null; try ResourceSpecification_tail Block catch (Throwable #t) { #primaryExc = #t; throw #t; } finally { if (Identifier != null) { if (#primaryExc != null) { try { Identifier.close(); } catch (Throwable #suppressedExc) { #primaryExc.addSuppressed(#suppressedExc); } } else { Identifier.close(); } } }}在第一个示例中,资源
R为
BufferedReader,
Identifieris
br和
expressionis为
newBufferedReader(newFileReader(filePath))。因此,仅
BufferedReader在隐式
finally块中关闭了。该
finally块不会调用
close,
FileReader因为它
不是 资源声明本身的一部分。 但是
,碰巧
BufferedReader.close()内部实现会调用
close包装的方法
FileReader。因此,第一个问题的答案是肯定的,因为包装对象将其关闭(遵循通常的观点,即资源在被释放时应该释放任何包装的资源),
而不是 因为
try-with-resources。
在第二个示例中:
private static BufferedReader buf1;public static void main(String[] args) throws IOException { //some pre try (BufferedReader buf2 = buf1) { } }答案取决于
somepre。在这里
buf2,
buf1两者都指向内存中的同一对象。如果此“某些代码”初始化
buf1为某个对象,则该对象将被关闭,因为
buf2它也引用了它。如果不是,并且
buf1为null(因此
buf2为null),则不会关闭任何内容,因为
finally上面显示的隐式中存在null检查。



