列出泛型协方差

Gre*_*989 0 java generics covariance

假设我们有2个不同的列表.

List 1可以采用任何Number参数(包括int,double,float和其他所有的Nu​​mber的子类).

 List<Number> l1 = new ArrayList();
Run Code Online (Sandbox Code Playgroud)

这样做非常好.

    l1.add(123);
    l1.add(123.3456);
Run Code Online (Sandbox Code Playgroud)

清单2扩展了数字.问题是我不能添加任何东西,我不明白为什么.另外,为什么我需要一个<?扩展Something>而不是仅仅创建层次结构中可以存储任何子类(如列表1)的最高类的列表?

List<? extends Number> l2 = new ArrayList();
    l2.add(123); //Error, although Integer is a subclass of Number
    l2.add(new Integer(123)); // Wrappers don't work either
    l2.add(123.456); //Error again
Run Code Online (Sandbox Code Playgroud)

rge*_*man 5

调用诸如add具有? extends通配符的类上的泛型参数 的方法的问题是编译器不知道确切的类型.它可以是a List<Number>或a List<Integer>或a List<Double>或a List<BigInteger>.编译器必须使用泛型保留类型安全性,如果允许这样的调用,则不会保留类型安全性.不应该允许您添加一个Double可能是a的列表List<Integer>.

这种? extends上限通配符本身可用作方法参数,其中确切类型无关紧要; 重要的是它的界限(在这种情况下Number)或以下.

public void foo(List<? extends Number> list) {
    for (Number n : list) {
       // do something with some kind of Number, don't care which
Run Code Online (Sandbox Code Playgroud)