使用超级关键字迭代通用列表

时间:2014-12-03 13:19:26

标签: java generics collections

我有以下2个课程:

class A {
    public String toString(){
        return "A Class";
    }
}

class B extends A {
    public String toString(){
        return "B Class";
    }
}

我有以下代码在将一些对象添加到列表后调用测试方法:

List<B> myList = new ArrayList<B>();
myList.add(new B());
myList.add(new B());

testList(myList);

现在,我的testList方法就是这样:

public void testList(List<? super B> aList){        
        for(A myObject : aList){  //This is showing compiler error
            System.out.println(myObject);
        }  

       for(B myObject : aList){  //Even this is showing compiler error
            System.out.println(myObject);
        }

       for(Object myObject : aList){  //This works fine
            System.out.println(myObject);
        }
}

为什么我不能使用AB的引用类型进行迭代。

testList mehtod中的列表声明与super关键字一致。

3 个答案:

答案 0 :(得分:9)

List<? super B> aList可以引用List<B>List<A>List<Object>,所以

for(A myObject : aList)

编译器不允许您使用A作为类型,因为它无法正确处理List<Object>,因为它也可能包含AB以外的元素{ {1}}是所有类的超类,例如Object(并使用String来处理A是错误的。)

出于同样的原因,您无法使用String(您将无法正确处理B)。此处只有List<A>是安全类型。

答案 1 :(得分:1)

您的列表已声明为包含B元素(即使B是A&#39,您可以将它们提取为A&#39; s)。所以你唯一能做的就是:

for(B myObject : aList){
  A a = myObject;
  System.out.println(a);
}

现在,您可以将列表更改为包含A(B&#39; s,因此您可以将B&#39;列入列表中):

List<A> myList = new ArrayList<A>();
myList.add(new B());
myList.add(new B());

然后

for(A myObject : aList){
  System.out.println(myObject);
}

答案 2 :(得分:1)

aList是用通配符定义的?所以编译器不知道aList的元素是什么类型。

尝试:

B object = aList.get(0);

也失败了。编译器不知道返回get方法的内容。