Java 带有通配符的列表会导致一般巫毒错误

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()

有人知道为什么下面的代码不能编译吗?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() ); //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