为什么在try-with-resources中获取`Stream <String>`时BufferedReader没有关闭?

The*_*tor 3 java java-8 try-with-resources java-stream autocloseable

当Stream在try-with-resources中使用a 时,应该关闭阅读器.

鉴于这种:

try(Stream<String> lines = new BufferedReader(reader).lines()) {
            return lines.map(it -> trim ? it.trim() : it)
                    .collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)

......读者没有被关闭?

此测试失败:

    AtomicBoolean closed = new AtomicBoolean(false);

    Reader r = new StringReader("  Line1 \n Line2") {

                @Override
                public void close() {
                    super.close();
                    closed.set(true);
                }

            };

    try(Stream<String> lines = new BufferedReader(r).lines()) {
            lines.map(it -> trim ? it.trim() : it)
                    .collect(Collectors.toList());
    }

    assertTrue("Reader was not closed.",closed.get());
Run Code Online (Sandbox Code Playgroud)

Adr*_*hum 8

我实际上没有使用try-resources语法.希望我的回答有意义.

根据我的理解,自动关闭是关闭声明中声明的资源,没有别的.

因此,try(Stream<String> lines = new BufferedReader(r).lines()) {只是关闭lines,而不是那个没有分配变量的缓冲读者.

如果你打算关闭缓冲的阅读器和流(你真的需要关闭流吗?),iirc,你可以在try语句中有多行:

try (BufferedReader br = new BufferedReader(r);
     Stream<String> lines = br.lines()) {
    //....
}
Run Code Online (Sandbox Code Playgroud)

这样的事情.(没有尝试编译,希望它的工作原理:P)

  • @SaintHill我认为这不合理.至少为什么它是这样设计的并不明显.我将在lambda-dev列表中提出问题. (4认同)
  • 我认为这也是合理的:)与装饰流的读者/流装饰器不同,关闭装饰器应关闭底层流.使用流完成(并关闭它)并不意味着底层读者无用且需要关闭.从概念上讲,我们可以进一步研究读者并再次获得另一个流. (3认同)
  • @SaintHill线程在这里:http://mail.openjdk.java.net/pipermail/lambda-dev/2013-December/thread.html我对这个解释印象不深 (3认同)