"resource leak: stream is never closed" 的背景
Background of "resource leak: stream is never closed"
给定一个使用流的 Java 函数:
List<String> function(List<String> input) {
Stream<String> a = input.parallelStream();
Stream<String> b = a.map(c -> c.toString());
return b.collect(Collectors.toList());
}
现在,我想控制是否通过参数进行映射。 Eclipse/the 编译器给我一个警告:资源泄漏:'a' 从未关闭
List<String> function(List<String> input, boolean doMap) {
Stream<String> a = input.parallelStream(); // Resource leak: 'a' is never closed
Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
return b.collect(Collectors.toList());
}
我可以使用 try-with-resources 语句解决这个问题:
List<String> function(List<String> input, boolean doMap) {
try (Stream<String> a = input.parallelStream()) {
Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
return b.collect(Collectors.toList());
}
}
我的问题是:当我使用流而不是 for 循环时,为什么会出现资源泄漏?如果我只是选择性地添加映射步骤,为什么会出现资源泄漏? (为什么第一个版本的函数没有资源泄漏?)有条件地组合处理流是否“危险”?我错过了什么?
我总结一下@Nikolas 换句话说再次回答:Java没有问题,但是“问题”(如果你想在all) 是变量。如果变量被声明为实现 AutoCloseable
的类型(并且 Stream
实现),Eclipse 显然会在此处报告警告,如果它没有找到对 [=12= 的调用,则它不会被关闭].
由于此错误与 Eclipse 相关,因此其他检查工具很可能不会对此失败,并且不需要“修复”即可通过此类检查。
根据我的理解,这显示了 Java 的一个基本问题,即它不会在不再需要时立即释放变量上的对象,而是在某个随机点释放它。有了资源,那就失败了。因此,资源必须由开发人员手动跟踪,在哪里关闭它们以及手动关闭它们。 Java 运行时将(假设)必须实现类似于 C++ 的 std::auto_ptr
的方法,那么这就没有必要了,如果删除了对资源的最后引用,则可以关闭它。但它不像 java "thinks".
给定一个使用流的 Java 函数:
List<String> function(List<String> input) {
Stream<String> a = input.parallelStream();
Stream<String> b = a.map(c -> c.toString());
return b.collect(Collectors.toList());
}
现在,我想控制是否通过参数进行映射。 Eclipse/the 编译器给我一个警告:资源泄漏:'a' 从未关闭
List<String> function(List<String> input, boolean doMap) {
Stream<String> a = input.parallelStream(); // Resource leak: 'a' is never closed
Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
return b.collect(Collectors.toList());
}
我可以使用 try-with-resources 语句解决这个问题:
List<String> function(List<String> input, boolean doMap) {
try (Stream<String> a = input.parallelStream()) {
Stream<String> b = doMap ? a.map(c -> c.toString()) : a;
return b.collect(Collectors.toList());
}
}
我的问题是:当我使用流而不是 for 循环时,为什么会出现资源泄漏?如果我只是选择性地添加映射步骤,为什么会出现资源泄漏? (为什么第一个版本的函数没有资源泄漏?)有条件地组合处理流是否“危险”?我错过了什么?
我总结一下@Nikolas 换句话说再次回答:Java没有问题,但是“问题”(如果你想在all) 是变量。如果变量被声明为实现 AutoCloseable
的类型(并且 Stream
实现),Eclipse 显然会在此处报告警告,如果它没有找到对 [=12= 的调用,则它不会被关闭].
由于此错误与 Eclipse 相关,因此其他检查工具很可能不会对此失败,并且不需要“修复”即可通过此类检查。
根据我的理解,这显示了 Java 的一个基本问题,即它不会在不再需要时立即释放变量上的对象,而是在某个随机点释放它。有了资源,那就失败了。因此,资源必须由开发人员手动跟踪,在哪里关闭它们以及手动关闭它们。 Java 运行时将(假设)必须实现类似于 C++ 的 std::auto_ptr
的方法,那么这就没有必要了,如果删除了对资源的最后引用,则可以关闭它。但它不像 java "thinks".