如何使用foreach迭代混合列表?

Adr*_*ter 1 java generics foreach

我想知道如何使用foreach迭代具有混合内容的List.请参阅下面的示例代码.

public class GenericsForeach {

    class A {
        void methodA() {
            System.out.println(getClass().getSimpleName() + ": A");
        }
    }

    class B extends A {
        void methodB() {
            System.out.println(getClass().getSimpleName() + ": B");
        }
    }

    void test() {

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

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

        List<? super A> mixed = new ArrayList<A>();
        mixed.addAll(listOfA);
        mixed.addAll(listOfB);

        Iterator<? super A> it = mixed.iterator();
        while (it.hasNext()) {
            A item = (A) it.next();
            item.methodA();
        }

        // XXX: this does not work
        // for (A item : mixed) {
        // item.methodA();
        // }
    }

    public static void main(String[] args) {
        new GenericsForeach().test();
    }
}
Run Code Online (Sandbox Code Playgroud)

我构建了两个具有不同但相关的内容类型AB(B扩展A)的列表.我将这两个列表添加到"混合"列表中,我声明它包含<? super A>类型.由于这个混合列表是"消费"类型A(或B)的项目,我应用了Bloch的PECS规则(Producer Extends,Consumer Super)来确定我需要<? super A>这里.

到现在为止还挺好.但是现在当我想迭代这个混合列表时,我似乎只能用一个Iterator<? super A>和一个演员来做A item = (A) it.next().当我尝试使用foreach循环(参见注释掉的代码)时,没有快乐:

类型不匹配:无法转换元素类型捕获#8-of?超级GenericsForeach.A到GenericsForeach.A

Eclipse甚至提供了有用的服务

将'item'的类型更改为'?超级A'

但这会导致灾难:

for (? super A item : mixed) {
    item.methodA();
}
Run Code Online (Sandbox Code Playgroud)

所以我不知道.Eclipse似乎不知道.这里有没有人知道这是否可行,如果不可能,为什么不呢?

Jon*_*eet 12

你只想List<A>mixed.我的推理:

  • 你希望能够添加类型的项目A,所以它不能List<? extends A>- 包括List<B>,你不能添加A到的项目.
  • 你希望能够保证您的项目获取的类型的A,所以它不可能是List<? super A>因为这可能是一个List<Object>不含A元素.

所以你最终得到:

List<A> mixed = new ArrayList<A>();
mixed.addAll(listOfA);
mixed.addAll(listOfB);

for (A item : mixed) {
  item.methodA();
}
Run Code Online (Sandbox Code Playgroud)