java泛型、通配符和通配符子类型-naturalNumberList.add(新的EvenNumber(20));生成错误消息

java泛型、通配符和通配符子类型-naturalNumberList.add(新的EvenNumber(20));生成错误消息,java,generics,wildcard,Java,Generics,Wildcard,我目前正在学习java泛型、通配符和通配符子类型。我已经想出了以下代码。但是,当我尝试使用这行代码将EvenNumber的实例添加到列表中时naturalNumberList.add(newevennumber(20)),显示了一条神秘的错误消息(见附图) 有人能给我解释一下为什么要添加(新的EvenNumber(20))生成错误?提前感谢您的帮助 public class NaturalNumber { private int i; public NaturalNumber(i

我目前正在学习java泛型、通配符和通配符子类型。我已经想出了以下代码。但是,当我尝试使用这行代码将
EvenNumber
的实例添加到列表中时
naturalNumberList.add(newevennumber(20)),显示了一条神秘的错误消息(见附图)

有人能给我解释一下为什么要添加(新的EvenNumber(20))生成错误?提前感谢您的帮助

public class NaturalNumber {
    private int i;
    public NaturalNumber(int i){
        this.i = i;
    }
}
class EvenNumber extends NaturalNumber {
    public EvenNumber(int i){
        super(i);
    }
}

class PSVM {
    public static void main(String[] args) {
        List<EvenNumber> evenNumberList = new ArrayList<>();
        List<? extends NaturalNumber> naturalNumberList = evenNumberList;
        evenNumberList.add(new EvenNumber(100));
        naturalNumberList.add(new EvenNumber(20));//error, for error message, see picture attached below
    }
}
公共类自然数{
私人互联网i;
公共自然编号(int i){
这个。i=i;
}
}
类EvenNumber扩展了自然数{
公共电话号码(int i){
超级(i);
}
}
类PSVM{
公共静态void main(字符串[]args){
List evenNumberList=newarraylist();

List它在这里的行为与您想象的完全不同

它有效地意味着变量可以保存列表实例
list
或其任何子类

现在编译器不允许您添加,因为它可能是其他子类的列表,如
list


通配符的真正用途是为方法参数增加灵活性

public void method(List<? extends NaturalNumber> list) 

public void方法(这里不需要通配符。它应该只在参数列表中使用。
public void method(List<? super NaturalNumber> list)