<?超级T>和<?在Java中扩展T>

问题:

List<? super T>List<? extends T>有什么区别?
我曾经使用List<? extends T>,但它不允许我添加元素list.add(e),而List<? super T>则是。

回答:

<代码>延伸

List<? extends Number> foo3的通配符表示这些声明是合法的作业:

List<? extends Number> foo3 = new ArrayList<Number>();  // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>();  // Double extends Number
  1.   – 考虑到上述可能的分配,您保证从List foo3读取什么类型的对象
     

    • You can read a Number because any of the lists that could be assigned to foo3 contain a Number or a subclass of Number.
    • You can’t read an Integer because foo3 could be pointing at a List<Double>.
    • You can’t read a Double because foo3 could be pointing at a List<Integer>.
  2.  写作 – 鉴于上述可能的作业,您可以添加List foo3类型的对象,这对所有上述可能的ArrayList作业是合法的:
     

    • You can’t add an Integer because foo3 could be pointing at a List<Double>.
    • You can’t add a Double because foo3 could be pointing at a List<Integer>.
    • You can’t add a Number because foo3 could be pointing at a List<Integer>.

 You can’t add any object to List<? extends T> because you can’t guarantee what kind of List it is really pointing to, so you can’t guarantee that the object is allowed in that List. The only “guarantee” is that you can only read from it and you’ll get a T or subclass of T.

<代码>超

现在考虑List <? super T>
List<? super Integer> foo3的通配符表示这些声明是合法的作业:

List<? super Integer> foo3 = new ArrayList<Integer>();  // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>();   // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>();   // Object is a superclass of Integer
  1.   – 考虑到上述可能的分配,当您从List foo3读取时,您保证接收什么类型的对象
     

    • You aren’t guaranteed an Integer because foo3 could be pointing at a List<Number> or List<Object>.
    • You aren’t guaranteed a Number because foo3 could be pointing at a List<Object>.
    • The only guarantee is that you will get an instance of an Object or subclass of Object (but you don’t know what subclass).
  2.  写作 – 鉴于上述可能的作业,您可以添加List foo3类型的对象,这对所有上述可能的ArrayList作业是合法的:
     

    • You can add an Integer because an Integer is allowed in any of above lists.
    • You can add an instance of a subclass of Integer because an instance of a subclass of Integer is allowed in any of the above lists.
    • You can’t add a Double because foo3 could be pointing at an ArrayList<Integer>.
    • You can’t add a Number because foo3 could be pointing at an ArrayList<Integer>.
    • You can’t add an Object because foo3 could be pointing at an ArrayList<Integer>.

佩奇

记住PECS“生产者延伸,消费超”

  •  “制作人延伸” – 如果您需要List生成T值(您想从列表中读取T),则需要使用? extends T声明它,例如List<? extends Integer>。但是你不能添加到这个列表。
  •  “消费超级” – 如果您需要List使用T值(您要将T写入列表),则需要使用? super T声明它,例如List<? super Integer>。但是不能保证您可以从此列表中读取什么类型的对象。
  • 如果您需要同时读取和写入列表,则需要使用无通配符来声明它。 List<Integer>

注意this example from the Java Generics FAQ。注意源列表src(生产列表)使用extends,目的地列表dest(消费列表)使用super

public class Collections {
public static void copy(List dest, List src) {
for (int i = 0; i < src.size(); i++) dest.set(i, src.get(i)); } } [/code] 另见  How can I add to List<? extends Number> data structures?

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: Difference between and in Java

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 5 = 2