[英]The signature of flatMap in Optional of Java 8
在oracle文檔中 ,它似乎是
<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
綁定到方法本身而不是類Optional
而且Optional
也是final
,當前簽名應該可以正常工作。
如果上述兩個條件不成立,則可以應用更改。 感謝@MalteHartwig提供的鏈接 。 讓我總結一下這個特定問題的答案。 很明顯,如果返回類型需要協變,后一個簽名(較長的簽名)在Java 8中是必需的。它不僅僅是關於繼承。 ? extends
在Optional<? extends U>
需要? 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
? extends
,將聲明? extends
傳播到要聲明方差的類型變量的(第二個)最外層。
假設你有class A
class B extends A
; 你需要記住,對象B
是A
對象; 你繼承了它。
為了使Object能夠實現Optional<? extends U>
Optional<? extends U>
約束,它必須滿足Optional<U>
約束。 同樣,為了使Object滿足Optional<U>
約束,它必須滿足Optional<? extends U>
Optional<? extends U>
。
在這種情況下,它們是同義詞。
雖然問題是針對某種方法的,但您可以相當容易地測試答案。 通過編寫類似的函數,您可以測試編譯器是否允許您想要的內容以及它是否會按預期運行。
public static <U> void List(List<U> A, List<? extends U> B) {
...
}
...
MakeList(new ArrayList<Number>(), new ArrayList<Integer>());
正如所料,一切都很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.