带有类型绑定的嵌套泛型会导致编译错误

时间:2018-02-17 20:26:23

标签: java generics

为什么会导致编译错误:

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

而以下不是?:

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

2 个答案:

答案 0 :(得分:2)

虽然Optional<Integer>Optional<? extends Number>的sybtype,但Optional<Optional<Integer>>不是Optional<Optional<? extends Number>>的子类型。如果您尝试将Optional<Integer>分配给Optional<Number>,即使Integer扩展Number,也会遇到相同的编译错误。

为了更好地理解,请将Optional<Integer> whith XOptional<? extends Number>替换为Y。你会得到:

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

XY的子类型,但Optional<X>不是Optional<Y>的子类型,它是Optional<? extends Y>

原来Optional<Optional<Integer>>Optional<? extends Optional<? extends Number>>的子类型。

现在考虑第二种情况:

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

此处编译器发现map的结果应为Optional<Optional<? extends Number>>,并尝试在map方法中推断出该类型。所以映射器函数

Function<? super T, ? extends U> mapper

变为

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

因为map返回Optional<U>而我们案例中的U被推断为Optional<? extends Number>

map完全返回我们需要的内容:

Optional<? extends Optional<? extends Number>>

回答你的评论

  

.map(x -> x)提供了哪些新信息?

.map(x -> x)帮助编译器推断出正确的类型

有用的资源:

答案 1 :(得分:1)

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);