【发布时间】:2023-03-26 06:17:01
【问题描述】:
在 IntelliJ IDEA 中调试我的代码时,当在流上使用连续的 flatMap 方法时,在某些情况下我无法停止异常。它不是在异常处停止,而是在第 271 行的 API 的 ReferencePipeline#flatMap 方法中停止,帧堆栈根本不显示异常。这是最简单的例子:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class AssertTest {
public static void main(String[] args) {
Arrays.asList(
Arrays.asList(0, 0, 0),
Arrays.asList(1, 1, 1),
Arrays.asList(2, 2, 2)
)
.stream()
.flatMap(a -> test1(a).stream())
.flatMap(a -> test2(a).stream())
.collect(Collectors.toSet());
}
private static List<List<Integer>> test1(List<Integer> ints) {
return Arrays.asList(ints);
}
private static List<List<Integer>> test2(List<Integer> ints) {
throw new RuntimeException();
}
}
这是我在调试器中运行代码时在 IDE 中看到的内容:
如果我注释掉.flatMap(a -> test1(a).stream()) 的行,那么它会按预期在异常处停止。断言也是如此(将 throw new RuntimeException() 替换为 assert false 并使用 -ea 运行)。
此问题仅与调试器有关:在程序因异常而崩溃后,堆栈跟踪包含发生异常的正确位置。
Exception in thread "main" java.lang.RuntimeException
at mypkg.AssertTest.test2(AssertTest.java:23)
at mypkg.AssertTest.lambda$main$1(AssertTest.java:16)
at mypkg.AssertTest$$Lambda$2/14008398.apply(Unknown Source)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at mypkg.AssertTest.main(AssertTest.java:17)
这是一个错误吗?如果是这样,是否在任何地方提到过?如果不是,我应该在哪里报告:Jetbrains、Oracle?或者这是正确的行为?
【问题讨论】:
-
你试过在测试方法中设置断点吗?
-
-
@Susei 我建议先联系 JetBrains,因为这涉及调试器。如果从调试器接口输出到 JVM 的信息缺失或不足,他们将能够确定这一点并将信息转发给 Oracle。
-
你试过把main方法中的大单行拆分成多行吗?将数组列表分配给变量,将stream()的结果分配给变量等。然后用异常断点重试。
-
是的,但我很想看看你是否在单行上遇到同样的问题,显示它是否是较低库的问题(因为它似乎是根据你的回答),或者如果它是只是 IntelliJ 不喜欢带有闭包的流畅界面风格。
标签: java intellij-idea java-8 java-stream