IntStream 何时真正关闭? SonarQube S2095 是 IntStream 的误报吗?

Posted

技术标签:

【中文标题】IntStream 何时真正关闭? SonarQube S2095 是 IntStream 的误报吗?【英文标题】:When is an IntStream actually closed? Is SonarQube S2095 a false positive for IntStream? 【发布时间】:2016-04-18 13:14:07 【问题描述】:

我正在使用 Java 8 流代替许多旧样式的 for 循环来遍历一堆结果并生成汇总统计信息。例如:

int messages = IntStream.rangeClosed(0, 7).map(ids::get).reduce(Integer::sum).getAsInt();

注意:我知道还有其他方法可以进行上面显示的计数。我这样做是为了说明我的问题。

我正在使用带有 Java 3.9 插件的 SonarQube 5.3。在该配置中,上面的代码行违反了 squid 规则 S2095:“资源应该关闭。”这就是我希望看到 AutoCloseable(例如 FileInputStream)是否已打开但从未关闭的结果。

所以这是我的问题:终端操作reduce 是否关闭了流?应该是?或者这是鱿鱼规则中的误报?

【问题讨论】:

IntStream 具有从 BaseStream 类继承的 onClose(Runnable closeHandler) 方法。您可以使用此处理程序检查流何时关闭或未关闭。 监控jira.sonarsource.com/browse/SONARJAVA-1478 【参考方案1】:

它没有关闭,因为AutoCloseable 接口只在try-with-resources 内部工作。但正如AutoCloseable 接口javadoc 中所说,IntStream 完全不需要这种关闭操作:

但是,当使用 java.util.stream.Stream 等工具时, 支持基于 I/O 和非基于 I/O 的形式,try-with-resources 使用非基于 I/O 的表单时,通常不需要块。

所以是的 S2095 是 IntStream 的误报。希望 SONARJAVA-1478 解决这个问题

【讨论】:

@BobCross 这确实是误报。 AutoClosable 接口在 Java 8 中发生了变化,现在 AutoClosable 可能实际上并不持有要关闭的资源。 静态分析不检测错误;它检测可能是错误的东西,可能值得一看。在这种情况下,您查看了它,并确定它不是错误,因为流不包含需要释放的资源。 @BrianGoetz 好吧,我们会尽最大努力避免浪费用户时间不去看那些不是错误的不值得的东西 :) @BobCross 这听起来确实是误报。我们将不得不微调此规则以排除实际上不持有资源的类型。在某些情况下,这最终会变得非常棘手。在实际开票处理此案之前,我想仔细看看,但我会将其链接到这个问题 @benzonico 好。我认为您想回去寻找流源(如果可以的话)并据此做出决定。我会关注文件中的静态流工厂方法(walk、lines 等)作为资源持有者。我不会担心像 BufferedReader.lines() 这样的方法,因为在这种情况下,流不是主要资源持有者,它是 BufferedReader,这就是需要关闭的东西(关闭结果流并不会关闭 BR .)

以上是关于IntStream 何时真正关闭? SonarQube S2095 是 IntStream 的误报吗?的主要内容,如果未能解决你的问题,请参考以下文章

何时在 C# 中使用线程池? [关闭]

角色属性与类[关闭]

PreApplicationStartMethod 何时真正被触发运行?

自动释放的对象何时真正释放?

什么时候应该使用访问者设计模式? [关闭]

BigQuery 流式传输和分区:_PARTITIONTIME 何时真正评估?