在java
中学习助焊剂(反应堆芯)时,我遇到以下有关功能的问题。
这是Flux.zip()
方法签名:
public static <I, O> Flux<O> zip(
final Function<? super Object[], ? extends O> combinator,
Publisher<?extends I>... sources) {
return zip(combinator, Queues.XS_BUFFER_SIZE, sources);
}
当我尝试调用此方法时:
Flux<User> userFluxFromStringFlux(Flux<String> usernameFlux, Flux<String> firstnameFlux, Flux<String> lastnameFlux) {
// predefined function taking object[] and returns User
Function<Object[], User> function = array -> new User(array[0].toString(),array[1].toString(), array[2].toString());
// it is working without error
Flux.zip(function, usernameFlux, firstnameFlux, lastnameFlux);
// this is also working without error
Flux.zip(array -> {
return new User(array[0].toString(),array[1].toString(), array[2].toString());
}, usernameFlux, firstnameFlux, lastnameFlux);
// but this has error with array[0] "Array type expected; found: 'org.reactivestreams.subscriber<capture<? super java.lang.object>>'"
Flux.zip(array -> new User(array[0].toString(),array[1].toString(), array[2].toString()), usernameFlux, firstnameFlux, lastnameFlux);
return null;
}
使用匿名函数的第三种方式,但是IDEA报告存在错误:
期望的数组类型;找到:'org.reactivestreams.subscriber>。
我想知道为什么使用带显式返回的预定义函数和匿名函数但匿名函数起作用?
感谢您的帮助。
答案 0 :(得分:1)
不是编译器专家,但我认为这与Java编译器看到的缩写形式lambda有歧义:是您传递内联Publisher
(因为它是功能接口)还是Function
?
之所以会造成这种混淆,是因为简短形式没有明确的return
语句:对于Publisher
选项,这意味着您创建了一个User
即可立即成为垃圾收集,但这不是编译器将禁止您执行的操作。
因此,假设lambda的目标类型为Publisher
,因此推断出array
为Subscriber
。但是然后在它上面使用了数组索引运算符,这肯定是错误的。
另一方面,将括号{ }
放入括号中可以消除这种含混不清之处,因为它具有一个似乎在推断中使用的显式return
类型。对于编译器,您不再可以表示Publisher
,因此使用下一个候选项(Function
)。
消除歧义的另一种方法是向编译器显示array
是...一个数组:
Flux.zip((Object[] array) -> new User(array[0].toString(),array[1].toString(), array[2].toString())
, usernameFlux, firstnameFlux, lastnameFlux);