I did supply a test that you can use to try it. What we are talking about is whether type Box<Parent> is substitutable by Box<Child> in the contravariant position. Intuitively we think we only need Box<? extends Parent> because we only care about the type parameter, but the type – as you point out – is actually different. Box<Parent> is not "inherited by" Box<Child>.
Specifically, if we have a consuming Box, and we replace it with a Box of a more specific type parameter, we could attempt feed the more general type into it, ie. a Box<Child> isn't going to appreciate having Parent fed to it. This is why covariance and mutable containers don't mix well, and why Java's covariant arrays are problematic. In this situation we have an immutable container, and we can substitute the type of our container with one of a more specific type, as it will only ever supply a value – and a value of Child will suffice as a Parent. So, for this case we need a Box that is substitutable, and therefore we need to add the covariance to our box. <? extends Box> is simply adding covariance to our Box type. For a much better explanation than I can give about this, see this excellent post describing generics in Scala, which – apart from have declaration-site variance and using [A] in place of <A> – generally follow the same pattern: http://termsandtruthconditions.herokuapp.com/blog/2012/12/29/covariance-and-contravariance-in-scala/ cheers, jed. On 14 July 2013 04:49, Henry Jen <henry....@oracle.com> wrote: > I think the type you talking about here is Optional<? extends U> instead > of ? extends Optional<U>. > > IIRC, Optional<? extends U> is not a subtype of Optional<U>, just like any > other Collection class. List<Child> is not a List<Parent>. > > Cheers, > Henry > > > On Jul 13, 2013, at 3:15 AM, Jed Wesley-Smith <j...@wesleysmith.io> wrote: > > > The ? extends Optional is unnecessary in flatMap as Optional is final. > > interestingly enough, it actually is. > > try the following test: > > class OptionalTest { > class Parent {}; > > class Child extends Parent {}; > > @Test public void covariantReturn() { > Optional<Parent> some = some(new Parent()); > Function<Parent, Optional<Child>> f = new Function<Parent, > Optional<Child>>() { > @Override public Optional<Child> apply(Parent p) { > return some(new Child()); > } > }; > Optional<Parent> mapped = some.<Parent> flatMap(f); > assertThat(mapped.get(), notNullValue()); > } > } > > adapted from the fugue test suite: > > > https://bitbucket.org/atlassian/fugue/src/96a65067fb7aaf1edae1bffa07167a5865cbebec/src/test/java/com/atlassian/fugue/OptionTest.java#cl-155 > > The point to remember is that Optional<Child> is a type and as such is > actually a subtype of Optional<Parent> – and therefore requires a > covariant return. > > cheers, > jed. > > > > > On 13 July 2013 04:15, Mike Duigou <mike.dui...@oracle.com> wrote: > >> The ? extends Optional is unnecessary in flatMap as Optional is final. >> Otherwise this looks good. >> >> Mike >> >> On Jul 5 2013, at 14:37 , Henry Jen wrote: >> >> > Hi, >> > >> > Please review the webrev at >> > >> > http://cr.openjdk.java.net/~henryjen/ccc/8015317.0/webrev/ >> > >> > Which adds following method to Optional, >> > >> > public static <T> Optional<T> ofNullable(T value) {} >> > public Optional<T> filter(Predicate<? super T> predicate) {} >> > public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {} >> > public<U> Optional<U> flatMap(Function<? super T, ? extends Optional<U>> >> > mapper) {} >> > >> > Also included is some cleanup on javadoc. >> > >> > Cheers, >> > Henry >> >> >> > >