为什么在发出终端操作后没有Java close()流? [英] Why doesn't Java close() stream after a terminal operation is issued?

查看:153
本文介绍了为什么在发出终端操作后没有Java close()流?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读 https://www.airpair.com/java/posts/spring-streams - 记忆效率,我很想从数据库中传出结果,但正如我与一位同事讨论过的那样(cfr。评论他添加到那篇文章中),人们需要记住使用try-with-resources构造以避免任何内存泄漏。


  1. 为什么在每个终端操作(无需在试运行中包装流实例化) -resources)?

  2. 如果适用,是否有任何将此功能添加到Java的计划,或者请求它是否有意义?


解决方案

因为需要显式资源释放的流实际上是一个非常不寻常的情况。因此,我们选择不对所有流执行负担,这些内容仅对.01%的使用有价值。



我们使Stream Autocloseable成为可以 从源中释放资源,但是这是我们停止的地方,并且好理由。



这样做不仅可以自动减轻大多数用户不需要的额外工作的负担,而且这也违反了一般原则:分配资源的人负责关闭资源。当你打电话

  BufferedReader reader = ... 
reader.lines()。op()。op() ...

是打开资源的那个,而不是流库,应该关闭它。实际上,由于关闭在某个资源保持对象上调用访问器方法而产生的流有时会关闭底层对象,因此您可能不希望该流关闭 BufferedReader 对你而言 - 你可能希望它在通话后保持开放状态。



如果你想关闭资源,这也很容易:

  try(BufferedReader reader = ...){
reader.lines()。op()...
}

您可能以特定的方式使用流,因此看起来很明显流应该做什么 - - 但是有比你更多的用例。因此,我们不是满足于特定的用例,而是从一般原则来处理它:如果您打开流,并且希望它关闭,请自行关闭它,但如果您没有打开它,则不能让您关闭。 / p>

After reading https://www.airpair.com/java/posts/spring-streams-memory-efficiency, I am tempted to stream results out of a database, but as I discussed with a colleague (cfr. comment he added to that article), one needs to remember to use the try-with-resources construct to avoid any memory leaks.

  1. Why doesn't the Java 8 library take care of closing streams itself after each terminal operation (without having to wrap the stream instantiation in a try-with-resources)?
  2. If applicable, are there any plans for this functionality to be added to Java, or would it make sense to request it?

解决方案

Because streams that require explicit resource release is actually a pretty unusual case. So we chose not to burden all stream execution with something that is only valuable for .01% of usages.

We made Stream Autocloseable so that you can release resources from the source if you want to, but this is where we stopped, and for a good reason.

Not only would doing this automagically burden the majority of users with extra work that they don't need, but this would also violate a general principle: he who allocates the resource is responsible for closing the resource. When you call

BufferedReader reader = ...
reader.lines().op().op()...

you are the one opening the resource, not the stream library, and you should close it. In fact, since closing a stream resulting from calling an accessor method on some resource-holding object will sometimes close the underlying object, you probably don't want the stream closing the BufferedReader for you -- you might want it to stay open after the call.

If you want to close the resource, this is easy too:

try (BufferedReader reader = ...) {
    reader.lines().op()...
}

You're probably using streams in a particular way, so it probably seems "obvious" what streams should do -- but there are more use cases out there than yours. So rather than catering to specific use cases, we approached it from the general principle: if you opened the stream, and you want it closed, close it yourself, but if you didn't open it, it's not for you to close.

这篇关于为什么在发出终端操作后没有Java close()流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆