Nested generic with type bound results in compile error

Why does this result in a compile error:

Optional<Optional<Integer>> a = Optional.of(Optional.of(1));
Optional<Optional<? extends Number>> b = a;

whereas the following does not?:

Optional<Optional<Integer>> a = Optional.of(Optional.of(1));
Optional<Optional<? extends Number>> c = a.map(x->x);

Although Optional<Integer> is a sybtype of Optional<? extends Number> Optional<? extends Number> , Optional<Optional<Integer>> is not a subtype of Optional<Optional<? extends Number>> Optional<Optional<? extends Number>> . You would get the same compile error if you tried to assign Optional<Integer> to Optional<Number> , even if Integer extends Number .

To understand it better, replace the Optional<Integer> whith X and Optional<? extends Number> Optional<? extends Number> with Y . You will get:

Optional<X> a = Optional.of(...);
Optional<Y> b = a;

X is a subtype of Y , but Optional<X> is not a subtype of Optional<Y> , it's a subtype of Optional<? extends Y> Optional<? extends Y>

Turns out that Optional<Optional<Integer>> is a subtype of Optional<? extends Optional<? extends Number>> Optional<? extends Optional<? extends Number>> Optional<? extends Optional<? extends Number>> .

Now consider the second case:

Optional<Optional<Integer>> a = Optional.of(Optional.of(1));
Optional<Optional<? extends Number>> c = a.map(x->x);

Here the compiler sees that the result of map should be Optional<Optional<? extends Number>> Optional<Optional<? extends Number>> and tries to infer that type in the map method. So the mapper function

Function<? super T, ? extends U> mapper

becomes

Function<? super Optional<Integer>, ? extends Optional<? extends Number>>

because map returns Optional<U> and U in our case is inferred as Optional<? extends Number> Optional<? extends Number>

And map returns exactly what we need:

Optional<? extends Optional<? extends Number>>

So answering your comment

What new information does the .map(x -> x) give?

.map(x -> x) helps the compiler to infer the right type

Helpful resources:

  • Wildcards and subtyping

  • Type Inference


  • Optional<Optional<Integer>> a = Optional.of(Optional.of(1));
    
    //Here the compiler can't infer that you have an Optional<? extends Number>
    Optional<Optional<? extends Number>> b = a;
    
    //This would be the correct syntax
    Optional<? extends Optional<? extends Number>> b = a;
    
    //Here the map takes a parameter 
    //Function<? extends Optional<Integer>, Optional<? extends Number>> 
    //the return value of map is exactly the type that the variable is expecting
    Optional<Optional<? extends Number>> c = a.map(x->x);
    
    链接地址: http://www.djcxy.com/p/41372.html

    上一篇: 直到用户事件,Qt窗口大小不正确

    下一篇: 与类型绑定的嵌套泛型导致编译错误