Search code examples
javagenericswildcardoption-typefinal

Wildcard extending final Optional class


The Optional class is declared as final in Java. Nevertheless, it contains two methods, flatMap and or with the following signatures:

public <U> Optional<U> flatMap​(Function<? super T,​ ? extends Optional<? extends U>> mapper)

and

public Optional<T> or​(Supplier<? extends Optional<? extends T>> supplier)

Optional can never be extended, so what is the point of the parts like ? extends Optional<...> in these signatures? Why not just Optional<...> ?

From answers to a similar question here about the final String class I only understood that the compiler doesn't have to reject such constructs. I agree with that, considering the examples that were given. But my question is rather focused on API design, not on the compiler ability to predict all possible use cases. Why did some ever need to allow for the possibility of, for example, a Supplier that yields instances of some impossible class extending Optional?


Solution

  • The class Optional is final, hence can not have subclasses, but it is generic, hence allows an infinite number of parameterized types having subtyping relationships on their own.

    For example, the following code is only valid due to the signature you’ve shown in the question:

    Optional<Object> o = Optional.empty();
    Supplier<Optional<String>> s = () -> Optional.of("str");
    Optional<Object> combined = o.or(s);
    

    An Optional<String> is not a subtype of Optional<Object>, so Optional<? extends T> is required in the signature, as an Optional<String> is a subtype of Optional<? extends Object>.

    But a Supplier<Subtype> is not a subtype of Supplier<Supertype>, so we need Supplier<? extends Supertype> to allow a supplier of the subtype whereas Optional<? extends T> is the supertype here.

    So Supplier<Optional<String>> is a subtype of Supplier<? extends Optional<? extends Object>>.