可以在 Java 中传递指向 Lambda 的引用变量
Can pass reference variable pointing to Lambda in Java
我尝试了一些 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 表达式的引用变量?
第一个示例中 fromStream
的参数类型错误。
在第二个片段中,它被正确地推断为 Supplier<Stream<? extends Long>>
,而在第一个片段中,你明确地 "narrowed" 它下降到 Flux.streamOf
.
不接受的东西
您可以通过以下方式修复第一个片段:
Supplier<Stream<? extends Long>> longStreamSupplier = ()
-> LongStream.iterate(0,
nextLong -> nextLong + 1).boxed();
Flux<Long> stream = Flux.fromStream(longStreamSupplier);
你可能会问自己
Why isn't there an overload for this function which accepts explicitly Supplier<Stream<T>>
instead of 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
的情况下,实现了更灵活的版本。
这是因为 longStreamSupplier
变量的类型为 Y<X<A>>
,而该方法需要一个类型为 Y<X<? extends A>>
的参数,而这些类型不可互换。
编辑
您可以更改变量类型以使第一个示例编译,
Supplier<Stream<? extends Long>> longStreamSupplier = ..
我尝试了一些 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 表达式的引用变量?
第一个示例中 fromStream
的参数类型错误。
在第二个片段中,它被正确地推断为 Supplier<Stream<? extends Long>>
,而在第一个片段中,你明确地 "narrowed" 它下降到 Flux.streamOf
.
您可以通过以下方式修复第一个片段:
Supplier<Stream<? extends Long>> longStreamSupplier = ()
-> LongStream.iterate(0,
nextLong -> nextLong + 1).boxed();
Flux<Long> stream = Flux.fromStream(longStreamSupplier);
你可能会问自己
Why isn't there an overload for this function which accepts explicitly
Supplier<Stream<T>>
instead ofSupplier<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
的情况下,实现了更灵活的版本。
这是因为 longStreamSupplier
变量的类型为 Y<X<A>>
,而该方法需要一个类型为 Y<X<? extends A>>
的参数,而这些类型不可互换。
编辑
您可以更改变量类型以使第一个示例编译,
Supplier<Stream<? extends Long>> longStreamSupplier = ..