簡體   English   中英

可選Java 8中flatMap的簽名

[英]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的用戶站點方差,即使Optionalfinal 我制作了一個代碼片段來演示它:

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 ; 你需要記住,對象BA對象; 你繼承了它。

為了使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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM