3 回答

TA貢獻1802條經驗 獲得超10個贊
我從 Stuart Marks 本人那里找到了背后的原因
http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-October/044026.html
這與嵌套泛型(Optional
嵌套在內部Function
)有關。從郵件線程
Function<..., Optional<StringBuilder>>不是的子類型
Function<..., Optional<? extends CharSequence>>為了解決這個問題,我們還必須添加外部通配符,這樣
Function<..., Optional<StringBuilder>>是一個子類型
Function<..., ? extends Optional<? extends CharSequence>>

TA貢獻1853條經驗 獲得超9個贊
FWIW,在 Java 11 中的Stream.iterate和Stream.iterate中仍然存在與協變參數類似的問題。當前的方法簽名是
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
這些簽名不允許某些UnaryOperator從類型角度來看合理的種子和 s 組合,例如,以下內容無法編譯:
UnaryOperator<String> op = s -> s;
Stream<CharSequence> scs = iterate("", op); // error
建議的解決方案是將方法簽名更改為
static <T, S extends T> Stream<T> iterate(S seed, Predicate<? super S> hasNext, UnaryOperator<S> next)
static <T, S extends T> Stream<T> iterate(S seed, UnaryOperator<S> f)
因此,與Optional.or和Optional.flatMap相比, 這是“附加類型參數方法”實際起作用的情況。

TA貢獻1921條經驗 獲得超9個贊
是的...據說帶有extends-bound(上限)的通配符使類型 covariant,這意味著例如List<Apple>是List<? extends Fruit>(考慮到Appleextends Fruit)的實際子類型;這也稱為協方差。
或者在您展示的示例中,這意味著它Optional<StringBuilder>是 的子類型Optional<? extends Optional<? extends CharSequence>>,因此您可以例如執行以下操作:
List<Optional<String>> left = new ArrayList<>();
List<? extends Optional<? extends CharSequence>> right = new ArrayList<>();
right = left; // will compile
或分配Function給另一個
添加回答
舉報