3

我有代码(完整源代码):

public class AutoConversionTest {

    @Test
    public void test_autoConversion() {
        Wrapper wrapper = new Wrapper();
        wrapper.setList(new ArrayList<Sub>());
        wrapper.addAll(new ArrayList<Sub>());
    }

    class Wrapper {
        List<? extends Super> list;

        public void setList(List<? extends Super> list) {
            this.list = list;
        }

        public void addAll(List<? extends Super> list) {
            this.list.addAll(list);  //TROUBLES!
        }
    }

    class Super {}

    class Sub extends Super {}
}

问题:Wy 错误以及如何解决?

编辑:我的错误日志

java: no suitable method found for `addAll(java.util.List<? extends expectations.public_method.experiments.AutoConversionTest.Super>)`
 method `java.util.List.addAll(int,java.util.Collection<? extends expectations.public_method.experiments.AutoConversionTest.Super>)` is not applicable (actual and formal argument lists differ in length)
 method `java.util.List.addAll(java.util.Collection<? extends expectations.public_method.experiments.AutoConversionTest.Super>)` is not applicable (actual argument `java.util.List<? extends expectations.public_method.experiments.AutoConversionTest.Super>` cannot be converted to `java.util.Collection<? extends expectations.public_method.experiments.AutoConversionTest.Super>` by method invocation conversion)
4

3 回答 3

7

List<? extends Super>意思是:一些未知类型的列表,它扩展了 Super。因此,您不能向这样的列表添加任何内容(null 除外),因为您不知道其元素的类型。如果编译器允许这样做,您可以将 的实例添加OtherSub到 a List<Sub>,这会破坏列表的类型安全性。

将类型更改Wrapper.listList<Super>

编辑:

修改后的代码:

class Wrapper {
    List<Super> list;

    public void setList(List<? extends Super> list) {
        this.list.clear();
        this.list.addAll(list);
    }

    public void addAll(List<? extends Super> list) {
        this.list.addAll(list);
    }
}
于 2013-07-30T09:53:54.627 回答
2

我推断您希望 Sub 类将 Super 类扩展为:

class Super {}
class Sub extends Super {}

即使您像上面那样编写类,通配符也会阻止您将任何内容添加到列表中,因为它仅用于只读列表。您可能可以使用类 Wrapper 来完成您的任务:

public class Wrapper<T extends Super> {

    private List<T> list = new ArrayList<T>();

    void doStuff(){
        List<Sub> al = new ArrayList<Sub>();
        for(Sub s : al)
            list.add((T) s);
    }

} 
于 2013-07-30T10:04:46.463 回答
2

List<? extends Super>意味着列表可以消耗任何未知数,只要它是 的Super子类Super

不幸的是,您不能将未知数(因为编译器不会通过某些“捕获”规则匹配元素的类型)添加到列表中,但 null 除外。

最好的原则是使用PECS原则(P roducer Extends, C onsumer S uper)。看你list是消费者,你应该List<? super Super>对消费者有一个未知数。

于 2013-07-30T09:58:44.050 回答