java 泛型、通配符和通配符子类型 - naturalNumberList.add(new EvenNumber(20));产生错误信息
java generic, wildcard and wildcard subtyping - naturalNumberList.add(new EvenNumber(20)); produces error message
我目前正在学习 java 泛型、通配符和通配符子类型化。我想出了以下代码。但是,当我尝试使用这行代码 naturalNumberList.add(new EvenNumber(20));
将 EvenNumber
的实例添加到列表时,显示了一条神秘的错误消息(见附图)。
有人可以向我解释一下为什么 naturalNumberList.add(new 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
}
}
错误信息:
它在这里的表现完全与您想象的不同。
这实际上意味着变量可以保存列表实例List<NaturalNumber>
或其任何子类。
现在编译器不允许你添加,因为它可能是一些其他子类的列表,如List<OddNumber>
。
通配符的真正用途是增加方法参数的灵活性。
public void method(List<? extends NaturalNumber> list)
您将无法向列表中添加任何内容,只能使用其现有元素。要允许添加,您必须使用:
public void method(List<? super NaturalNumber> list)
这里无法保证元素的类型,只能取Objects
Remember the rule: PECS. Producer extends, consumer super.
如果您希望既能取又能加,则不能使用通配符。
我目前正在学习 java 泛型、通配符和通配符子类型化。我想出了以下代码。但是,当我尝试使用这行代码 naturalNumberList.add(new EvenNumber(20));
将 EvenNumber
的实例添加到列表时,显示了一条神秘的错误消息(见附图)。
有人可以向我解释一下为什么 naturalNumberList.add(new 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
}
}
错误信息:
它在这里的表现完全与您想象的不同。
这实际上意味着变量可以保存列表实例List<NaturalNumber>
或其任何子类。
现在编译器不允许你添加,因为它可能是一些其他子类的列表,如List<OddNumber>
。
通配符的真正用途是增加方法参数的灵活性。
public void method(List<? extends NaturalNumber> list)
您将无法向列表中添加任何内容,只能使用其现有元素。要允许添加,您必须使用:
public void method(List<? super NaturalNumber> list)
这里无法保证元素的类型,只能取Objects
Remember the rule: PECS. Producer extends, consumer super.
如果您希望既能取又能加,则不能使用通配符。