如何在Java中实现Stream而不出现资源泄漏警告

2024-03-15

我希望实施Stream<E>接口(我承认,这是不必要的大接口)并添加一个构建器方法foo().

public MyStream<E> implements Stream<E>, ExtendedStream<E> {

    private final Stream<E> delegate;

    public MyStream(final Stream<E> stream) {
        this.delegate = stream;
    }

    // a sample Stream<E> method implementation
    @Override
    public <R> MyStream<R> map(Function<? super E, ? extends R> mapper) {
        return new MyStream<>(this.delegate.map(mapper));
    }
    // the rest in the same way (skipped)

    // a method from ExtendedStream<E>
    @Override
    public MyStream<E> foo() {
        return new MyStream(this.delegate.......);
    }  
}

到目前为止,一切都很好。

long count = new MyStream(list.stream())
    .map(i -> i * 10)
    .foo()
    .filter(i -> i > 100)
    .count();

我遇到了麻烦Closeable的行为Stream。的文档Stream https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html关于关闭(格式化我的)的说明:

流有一个BaseStream.close()方法与实施AutoCloseable,但几乎所有流实例实际上并不需要在使用后关闭。一般来说,只有源是 IO 通道的流(例如由Files.lines(Path, Charset))将需要关闭。

关闭 Stream 的唯一方法是flatMap or close.

对象的实例化在日食氧气带有下划线并带有警告:

资源泄漏:'<unassigned Closeable value>' 永远不会关闭

这不能重现IntelliJ Idea 2018.1.5。我浏览过的相关问题是here https://stackoverflow.com/questions/11463327/is-this-a-memory-leak-or-a-false-positive and here https://stackoverflow.com/questions/23779163/potential-resource-leak-unassigned-closeable-with-a-hashmap。我明白了Closeable问题与File or Dictionary,但是,我被 Streams 困住了。

I dislike the static method MyStream.of(...) calling a private constructor workaround.


作为工作的一部分JSR 335 https://www.jcp.org/en/jsr/detail?id=335,JRE 库通过引入java.util.Stream同时在一些地方利用新概念java.nio。在此期间,JSR 335 专家组咨询了 Eclipse 团队,讨论了以下内容conflict:

  • 当程序员忘记关闭抗 GC (GCR) 资源(例如,FileInputStream.

  • 图书馆团队计划制作java.util.Stream的一个子类型AutoCloseable允许在 try-with-resource 中使用,其动机是j.u.Stream could 潜在地由 GCR 资源支持。尽管如此,默认的假设应该是j.u.Stream do not需要一个close() call.

  • 尽管如此,某些方法java.nio返回j.u.Stream require to be close()d.

EG 和 Eclipse 一致认为没有简单的解决方案可以发现这样只需查看可关闭的类型任何工具都可以准确识别是否需要关闭。这是由于各种资源错综复杂造成的wrapping多个级别的其他资源。特别是类型j.u.Stream没有指示实例是否由 GCR 资源支持。

对于一个干净的解决方案,有人进一步提到,需要一个类型注释系统(使用 JSR 308)来用精确静态分析所需的信息来丰富类型系统。据我所知,这种方法直到今天才得以实现。

作为折衷方案,建议像 Eclipse 这样的工具实现者按照以下方式对启发式进行编码:

  • 通常,类型的所有实例AutoCloseable应该关闭。

  • 以下已知类型集将被排除在分析之外,因为这些类型通常不需要关闭:java.util.Stream and {Int,Long,Double}Stream.

  • 作为异常中的异常,某些返回 Stream 的静态方法java.nio众所周知require关闭。

讨论基本上发生在 lambda-libs-spec-observers 邮件列表上的以下两篇帖子之间:

  • Brian 的问题陈述和中间提案 http://mail.openjdk.java.net/pipermail/lambda-libs-spec-observers/2013-June/002170.html

  • 我对一次私人讨论的总结 http://mail.openjdk.java.net/pipermail/lambda-libs-spec-observers/2013-June/002163.html.

历史就这么多了。

2013年的讨论没有考虑到自定义实现 of j.u.Stream。 Eclipse 假设没有关于这些实现的具体知识。如果不是该工具会决定需要/不需要 close() 的偏见,那就更好了,但是如果实现者(这里是MyStream) 将有办法指示此类的实例是否需要关闭。然而,迄今为止的实施者还没有办法表达这一点。

由于缺乏完整且精确的选项,我们可以讨论扩展启发式集,这样不仅可以使已知的类型集j.u.Stream家人,也它的所有亚型被排除在分析之外,并被认为是 GC 友好的。显然,这种方法会增加漏报的风险(分析遗漏的错误)。

正如 howlger 的答案所建议的那样,将警告标记为“潜在泄漏”会令人困惑,因为在流分析中,“潜在”一词通常应该表示程序中某些(但不是全部)流上发生的行为。

截至今天,可用选项有:

  • Using @SuppressWarnings("resource")无论在哪里MyStream使用(优选)

  • 降低此特定问题的严重性(如果使用MyStream使用第一个选项的范围太广)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在Java中实现Stream而不出现资源泄漏警告 的相关文章

  • eclipse行号状态行贡献项是如何实现的?

    我需要更新状态行编辑器特定的信息 我已经有了自己的实现 但我想看看 eclipse 贡献项是如何实现的 它显示状态行中的行号 列位置 谁能指点一下 哪里可以找到源代码 提前致谢 亚历克斯 G 我一直在研究它 它非常复杂 我不确定我是否了解完
  • Java 的支持向量机?

    我想用Java编写一个 智能监视器 它可以随时发出警报detects即将到来的性能问题 我的 Java 应用程序正在以结构化格式将数据写入日志文件
  • 什么是抽象类? [复制]

    这个问题在这里已经有答案了 当我了解抽象类时 我说 WT H 问题 创建一个无法实例化的类有什么意义呢 为什么有人想要这样的课程 什么情况下需要抽象类 如果你明白我的意思 最常见的是用作基类或接口 某些语言有单独的interface构建 有
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • Runtime.exec 处理包含多个空格的参数

    我怎样才能进行以下运行 public class ExecTest public static void main String args try Notice the multiple spaces in the argument Str
  • Android 无法解析日期异常

    当尝试解析发送到我的 Android 客户端的日期字符串时 我得到一个无法解析的日期 这是例外 java text ParseException 无法解析的日期 2018 09 18T00 00 00Z 位于 偏移量 19 在 java t
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • 在 Java 中获取并存储子进程的输出

    我正在做一些需要我开始子处理 命令提示符 并在其上执行一些命令的事情 我需要从子进程获取输出并将其存储在文件或字符串中 这是我到目前为止所做的 但它不起作用 public static void main String args try R
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • 不可变的最终变量应该始终是静态的吗? [复制]

    这个问题在这里已经有答案了 在java中 如果一个变量是不可变的并且是final的 那么它应该是一个静态类变量吗 我问这个问题是因为每次类的实例使用它时创建一个新对象似乎很浪费 因为无论如何它总是相同的 Example 每次调用方法时都会创
  • 轻松的反应

    我有一个与这里描述的类似的案例 动态更改RESTEasy服务返回类型 https stackoverflow com questions 3786781 dynamically change resteasy service return
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • 手动设置Android Studio的JDK路径

    如何为 Android Studio 使用自定义 JDK 路径 我不想弄乱 PATH 因为我没有管理员权限 是否有某个配置设置文件允许我进行设置 如果您查看项目设置 您可以从那里访问 jdk 在标准 Windows 键盘映射上 您可以在项目
  • Android S8+ 警告消息“不支持当前的显示尺寸设置,可能会出现意外行为”

    我在 Samsung S8 Android 7 中收到此警告消息 APP NAME 不支持当前的显示尺寸设置 可能会 行为出乎意料 它意味着什么以及如何删除它 谢谢 通过添加解决supports screens 机器人 xlargeScre
  • 列表过滤器内的 Java 8 lambda 列表

    示例 JSON id 1 products id 333 status Active id 222 status Inactive id 111 status Active id 2 products id 6 status Active
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • Android View Canvas onDraw 未执行

    我目前正在开发一个自定义视图 它在画布上绘制一些图块 这些图块是从多个文件加载的 并将在需要时加载 它们将由 AsyncTask 加载 如果它们已经加载 它们只会被绘制在画布上 这工作正常 如果加载了这些图片 AsyncTask 就会触发v
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似

随机推荐