Ответ 1
Прежде всего, IMO, поскольку U
связывается с самим методом, но не с классом Optional
, а также Optional
является final
, текущая подпись должна работать нормально.
Если оба указанных выше условия не выполняются, могут быть применены изменения. Спасибо за ссылку , предоставленную @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
, которая будет распространять это декларацию вплоть до (2-го) внешнего уровня от переменной типа, для которой вы хотите объявить дисперсию.