为什么这个带有限通配符的Java通用代码不能编译?

时间:2017-08-13 10:50:26

标签: java generics type-parameter bounded-wildcard

当我读到这个我无法理解的源代码示例时,我正在阅读superb Java Generics FAQ by Angelika Langer

import java.util.List;
import java.util.ArrayList;
import java.lang.Number;
import java.lang.String;
import java.lang.Long;

class X<T extends List<? extends Number>> {
    public void someMethod(T t) {
        t.add(new Long(0L));    // error
        Number n = t.remove(0);
    }
}

我无法理解为什么编译器无法推断出&#34; Long扩展数字&#34;并将其与&#34;?相匹配扩展数字&#34;在类型擦除之前,使<? extends Number>完全没用。

我已经阅读了常见问题解答,所以我正在寻找更简单的解释以及替代方案。

提前致谢

1 个答案:

答案 0 :(得分:2)

假设某人以这种方式使用您的课程:

List<Double> list = new ArrayList<>();
X<List<Double>> x = new X<>();
x.someMethod(list);

现在,您的方法会尝试将Long添加到List<Double>。这就是编译器不允许的原因。

您无法向Long添加List<? extends Number>,因为List<? extends Number>可以分配List<Double>List<Integer>等等。

您可以将类声明更改为X<T extends List<Number>>,这将解决编译错误,因为List<Number>您总是可以添加Long(或任何其他子实例)类Number)。