在oracle docs , 它似乎是
<U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)
对于 mapper
作为 Function
,它使参数逆变但不使返回类型协变。我想知道 mapper
是否可以(应该)是
Function<? super T,Optional<? extends U>>
或
Function<? super T, ? extends Optional<? extends U>>
?
最佳答案
首先,IMO,因为U
绑定(bind)到方法本身而不是类 Optional
还有Optional
是final
,当前签名应该可以正常工作。
如果上述两个条件中的任何一个不成立,则可以应用更改。感谢 link由@MalteHartwig 提供。让我总结一下这个特定问题的答案。很明显,如果返回类型需要协变,那么在 Java 8 中后一个签名(较长的签名)是必需的。这不仅仅是关于继承。 ? extends
在 Optional<? extends U>
前面需要声明 Function
的用户站点方差即使Optional
是final
.我做了一个代码片段来演示它:
import java.util.function.Function;
class A {}
class B extends A {}
final public class Option<T> {
private T value;
public Option(T v) { value = v; }
<U> Option<? extends U> flatMap1(Function<? super T, Option<? extends U>> mapper) {
return mapper.apply(value);
}
<U> Option<? extends U> flatMap2(Function<? super T, ? extends Option<? extends U>> mapper) {
return mapper.apply(value);
}
void test() {
Option<A> oa = new Option<>(new A());
Function<A,Option<A>> faa = (A a) -> new Option<>(new A());
Function<A,Option<B>> fab = (A a) -> new Option<>(new B());
//oa.flatMap1(faa); DOES NOT COMPILE
oa.flatMap2(fab);
}
}
似乎由于 Java 只有用户站点方差声明,您可能需要一系列 ? extends
从要为其声明方差的类型变量一直将该声明传播到(第二)最外层。
关于java - Java 8 Optional中flatMap的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48124416/