0

我正在尝试一些 Spring 反应式代码,以下是相关的代码

Supplier<Stream<Long>> longStreamSupplier = ()
            -> LongStream.iterate(0,
                    nextLong -> nextLong + 1).boxed();

Flux<Long> fooIds = Flux.fromStream(longStreamSupplier); 

上面的最后一行在 Intellj IDE 中给出了编译错误,说没有接受该类型的方法。

但是,如果我将其转换为以下内容:

Flux<Long> fooIds = Flux.fromStream(() -> LongStream
                    .iterate(0, nextLong -> nextLong + 1)
                    .boxed());

这工作正常。为什么它不能接受指向我在第二段代码中传递的同一个 lambda 表达式的引用变量?

4

2 回答 2

2

fromStream在第一个示例中,您的参数类型错误。在第二个片段中,它被正确推断为Supplier<Stream<? extends Long>>,而在第一个片段中,您明确地将其“缩小”到不被Flux.streamOf.

您可以通过编写来修复第一个片段:

        Supplier<Stream<? extends Long>> longStreamSupplier = ()
                -> LongStream.iterate(0,
                nextLong -> nextLong + 1).boxed();

        Flux<Long> stream = Flux.fromStream(longStreamSupplier);

你可能会问自己

为什么这个函数没有重载,它明确接受Supplier<Stream<T>>而不是 Supplier<Stream<? extends T>>.

那是因为 Java 类型擦除,请考虑以下两个函数:


    private void foo(Supplier<Stream<? extends  Long>> stream) {

    }
    private void foo(Supplier<Stream<Long>> stream) {

    }

编译时,类型擦除后,我们留下:


    private void foo(Supplier stream) {

    }
    private void foo(Supplier stream) {

    }

这会产生编译错误,因为我们有两个定义相同的函数。所以在 的情况下Flux::fromStream,实现了更灵活的版本。

于 2020-03-08T10:44:06.880 回答
1

那是因为longStreamSupplier变量有 type Y<X<A>>,而方法需要一个带有 type 的参数Y<X<? extends A>>,并且这些类型是不可互换的。

编辑

您可以更改变量类型以编译第一个示例,

Supplier<Stream<? extends Long>> longStreamSupplier = ..
于 2020-03-08T11:01:57.767 回答