switchif空链导致StackOverflower错误

dy2hfwbg  于 2021-07-12  发布在  Java
关注(0)|答案(1)|浏览(373)

以下代码导致StackOverflower错误。这是在编写这样的代码时应该发生的,还是需要在框架中解决的问题?
该代码已经过测试 rxjava-2.2.19 . 可以在这里找到来源。

样品

下面的代码基于我们用来完成某种带中断条件的循环的代码(参见 flowable = flowable.switchIfEmpty(third(s)) ). 显然,这种方法效果不太好。

public class SwitchIfEmptyTest {

    public static void main(String[] args) {
        SwitchIfEmptyDemo demo = new SwitchIfEmptyDemo();
        demo.one("foo")
                .blockingForEach(s -> System.out.println(s));
    }

    static class SwitchIfEmptyDemo {

        private SomeSource source = new SomeSource();

        public Flowable<String> one(String input) {
            return Flowable.<String>empty()
                    .switchIfEmpty(two(input));
        }

        public Flowable<String> two(String input) {
            return Flowable.<String>create(emitter -> {
                emitter.onNext(input);
                emitter.onComplete();
            }, BackpressureStrategy.ERROR)
                    .flatMap(inputFlowable -> {
                        return source.read()
                                .toList()
                                .toFlowable()
                                .flatMap(strings -> {
                                    Flowable<String> flowable = Flowable.empty();
                                    for (String s : strings) {
                                        flowable = flowable.switchIfEmpty(third(s));
                                    }
                                    return flowable;
                                });
                    });
        }

        public Flowable<String> third(String input) {
            //System.out.println("Value " + input);
            return Flowable.empty();
        }
    }

    static class SomeSource {

        public Flowable<String> read() {
            return Flowable.create(emitter -> {
                for (int i = 0; i < 1_000_000; i++) {
                    emitter.onNext("Some values " + i);
                }
                emitter.onComplete();
            }, BackpressureStrategy.ERROR);
        }
    }
}

堆栈跟踪

Exception in thread "main" java.lang.StackOverflowError
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at io.reactivex.Flowable.subscribe(Flowable.java:14939)
at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
...
rekjcdws

rekjcdws1#

为了消除StackOverflowerr错误,一种可能是使用 takeWhile 运算符(请参阅完全差异)。

public Flowable<String> two(String input) {
    return Flowable.<String>create(emitter -> {
        emitter.onNext(input);
        emitter.onComplete();
    }, BackpressureStrategy.ERROR)
            .flatMap(inputFlowable -> {
                return source.read()
                        .flatMap(this::third)
                        .takeWhile(s -> s.equals("false"));
            });
}

相关问题