简体   繁体   English

泛型:尝试将参数化集合传递给List addAll方法

[英]Generics: try pass parametrized collection to List addAll method

I have code (full source code): 我有代码(完整的源代码):

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 {}
}

Question : Wy error and how to sovle it? 问题 :Wy错误以及如何解决它?

EDITED : my error log 编辑 :我的错误日志

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)

List<? extends Super> List<? extends Super> means: a list of some unknown type, which extends Super. List<? extends Super>意思是:一个未知类型的列表,它扩展了Super。 So, you can't add anything (except null) to such a list, since you don't know the type of its elements. 因此,您不能向此类列表添加任何内容(null除外),因为您不知道其元素的类型。 If this was allowed by the compiler, you could add instances of OtherSub to a List<Sub> , which would ruin the type-safety of the list. 如果编译器允许这样做,您可以将OtherSub实例添加到List<Sub> ,这会破坏列表的类型安全性。

Change the type of Wrapper.list to List<Super> . Wrapper.list的类型更改为List<Super>

EDIT: 编辑:

Modified code: 修改后的代码

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);
    }
}

List<? extends Super> List<? extends Super> means the list can consume any unknowns as long is it is a Super class of a child of Super . List<? extends Super>意味着列表可以消耗任何未知数,只要它是Super的孩子的Super

Unfortunately, you cannot add an unknown (as the compiler wouldn't match the type of element through some "capture of" rules) to a list, except null. 不幸的是,你不能添加一个未知的(因为编译器不会通过一些“捕获”规则将元素的类型匹配)到列表,除了null。

The best principle is to use the PECS principle ( P roducer E xtends, C onsumer S uper). 最好的原则是使用PECS原理( P roducer E xtends, C onsumer S uper)。 Seeing your list is a consumer, you should have a List<? super Super> 看到您的list是消费者,您应该有一个List<? super Super> List<? super Super> to consumer unknowns. List<? super Super>消费者未知数。

I infer you want the class Sub to extend class Super as: 我推断你希望类Sub将类Super扩展为:

class Super {}
class Sub extends Super {}

Even if you write the classes as above, the wildcard prevents you from adding anything to a list, since it serves only for read-only lists. 即使您按上述方式编写类,通配符也会阻止您向列表添加任何内容,因为它仅用于只读列表。 You can probably do your task with the class Wrapper as: 您可以使用类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);
    }

} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM