Java 带有通配符的列表会导致一般巫毒错误
有人知道为什么下面的代码不能编译吗?add()和addAll()都不能按预期工作。删除“?extends”部分可以使一切正常工作,但这样我就无法添加Foo的子类Java 带有通配符的列表会导致一般巫毒错误,java,generics,generic-list,generic-collections,Java,Generics,Generic List,Generic Collections,有人知道为什么下面的代码不能编译吗?add()和addAll()都不能按预期工作。删除“?extends”部分可以使一切正常工作,但这样我就无法添加Foo的子类 List<? extends Foo> list1 = new ArrayList<Foo>(); List<? extends Foo> list2 = new ArrayList<Foo>(); /* Won't compile */ list2.add( new Foo()
List<? extends Foo> list1 = new ArrayList<Foo>();
List<? extends Foo> list2 = new ArrayList<Foo>();
/* Won't compile */
list2.add( new Foo() ); //error 1
list1.addAll(list2); //error 2
List记住PECS:
由于您试图将项目添加到列表2中,因此它是消费者,不能声明为List它们是错误。考虑到Bar
和Baz
是扩展Foo
的两种不同类型,让我们修改代码:
List<? extends Foo> list1 = new ArrayList<Bar>();
List<? extends Foo> list2 = new ArrayList<Baz>();
List对不起,也许我误解了你的问题,但是:
public class Bar extends Foo{ }
此代码:
List<Foo> list2 = new ArrayList<Foo>()
list2.add( new Bar() );
List list2=new ArrayList()
列表2.添加(新条());
不要为我生成任何错误
因此,删除通配符可以添加Foo的子类。(我在这里假设Bar
和Baz
都是Foo
的子类型)
List<? extends Foo> list1 = new ArrayList<Foo>();
List<? extends Foo> list2 = new ArrayList<Foo>();
/* Won't compile */
list2.add( new Foo() ); //error 1
list1.addAll(list2); //error 2
List让我试着解释一下在什么情况下你可能需要使用请解释一下你为什么使用Hey,Ingo。这是一个很好的观点,也是一个可能在早些时候创造出更好/更准确答案的观点。我对使用通配符接受子类型的方法参数感到困惑,认为需要使用问题中的List@Vivien字体我知道。我所说的是,通配符可以被删除以便代码编译。它将允许添加Foo的子类。谢谢,Paulo!迈克尔·迈尔斯的链接答案也很中肯,但你的答案不需要绕道:)谢谢你的帮助-链接页面上的PECS答案非常棒!向上投票支持你的链接答案,但授予保罗认可答案的荣誉,因为它不需要绕道就可以做到全面:)我看不出列出爸爸和列出孙子之间有什么区别,不是吗?
List<? extends Foo> list1 = new ArrayList<Bar>();
List<? extends Foo> list2 = new ArrayList<Baz>();
public class Bar extends Foo{ }
List<Foo> list2 = new ArrayList<Foo>()
list2.add( new Bar() );
class Grand {
private String name;
public Grand(String name) {
this.setName(name);
}
public Grand() {
}
public void setName(String name) {
this.name = name;
}
}
class Dad extends Grand {
public Dad(String name) {
this.setName(name);
}
public Dad() {
}
}
List<Dad> dads = new ArrayList<>();
dads.add(new Dad("Dad 1"));
dads.add(new Dad("Dad 2"));
dads.add(new Dad("Dad 3"));
List<Dad> grands = new ArrayList<>();
dads.add(new Dad("Grandpa 1"));
dads.add(new Dad("Grandpa 2"));
dads.add(new Dad("Grandpa 3"));
List<Grand> resultList;
resultList = dads; // Error - Incompatable types List<Grand> List<Dad>
resultList = grands;//Works fine
List<? extends Grand> resultList;
resultList = dads; // Works fine
resultList = grands;//Works fine