我有代码(完整的源代码):
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)
答案 0 :(得分:7)
List<? extends Super>
表示:一些未知类型的列表,它扩展了Super。因此,您不能向此类列表添加任何内容(null除外),因为您不知道其元素的类型。如果编译器允许这样做,您可以将OtherSub
的实例添加到List<Sub>
,这会破坏列表的类型安全性。
将Wrapper.list
的类型更改为List<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);
}
}
答案 1 :(得分:2)
List<? extends Super>
表示该列表可以使用任何未知数,只要它是Super
的子Super
类。
不幸的是,你不能添加一个未知的(因为编译器不会通过某些“捕获”规则将元素的类型与列表匹配),除了null。
最好的原则是使用 PECS 原则( P roducer E xtends, C onsumer S uper)。看到您的list
是消费者,您应该有List<? super Super>
消费者未知数。
答案 2 :(得分: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);
}
}