[英]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.