【问题标题】:Not being able to stop at exception when using consecutive stream.flatMap使用连续 stream.flatMap 时无法停止异常
【发布时间】: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 -&gt; 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


【解决方案1】:

这是我在报告错误后从 Jetbrains 开发人员那里得到的答案:

http://youtrack.jetbrains.com/issue/IDEA-126981?replyTo=27-763411

只有在设置任何异常断点以仅在未捕获的异常上停止时才能重​​现它,是这样吗?

你的异常在java中被捕获并重新抛出,这是一个缺点 的流:(您还需要停止捕获的异常 能够在您的代码中停止。

启用在捕获的异常处停止为我解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2020-12-08
    • 2014-12-27
    • 2012-06-16
    • 1970-01-01
    • 2012-08-24
    相关资源
    最近更新 更多