本文介绍了< 之间的区别?超级T>和 <?

问题描述

List<有什么区别?List ?

我曾经使用 List,但它不允许我向它添加元素 list.add(e),而 List 确实如此.

I used to use List<? , but it does not allow me to add elements to it list.add(e), whereas the List<? does.

推荐答案

List 表示这些都是合法的赋值:

The wildcard declaration of List<? means that any of these are legal assignments:

List<? 
  1. 读取 - 鉴于上述可能的分配,您保证从 List foo3 读取什么类型的对象:

  1. Reading - Given the above possible assignments, what type of object are you guaranteed to read from List foo3:

  • 您可以读取 Number 因为任何可以分配给 foo3 的列表都包含一个 NumberNumber 的子类.
  • 您无法读取 Integer,因为 foo3 可能指向 List.
  • 您无法读取 Double,因为 foo3 可能指向 List.
  • 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>.

Writing - 鉴于上述可能的分配,您可以将什么类型的对象添加到 List foo3所有人> 以上可能的 ArrayList 赋值:

Writing - Given the above possible assignments, what type of object could you add to List foo3 that would be legal for all the above possible ArrayList assignments:

  • 您不能添加 Integer,因为 foo3 可能指向 List.
  • 您不能添加 Double,因为 foo3 可能指向 List.
  • 您不能添加Number,因为foo3 可能指向List.
  • 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>.

您不能将任何对象添加到 List 因为你不能保证它真正指向的是什么类型的 List,所以你不能保证该对象在那个 List 中是允许的>.唯一的保证"是您只能从中读取,并且您将获得 TT 的子类.

You can't add any object to List<? 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 <?超级T>.

List 表示这些都是合法的赋值:

The wildcard declaration of List<? means that any of these are legal assignments:

List<? 
  1. 阅读 - 鉴于上述可能的分配,当您从 List foo3 中读取时,您保证会收到什么类型的对象:

  1. Reading - Given the above possible assignments, what type of object are you guaranteed to receive when you read from List foo3:

  • 不能保证 Integer 因为 foo3 可能指向 ListList.
  • 不能保证Number,因为foo3 可能指向List.
  • 唯一的保证是您将获得Object 的实例或Object 的子类(但你不知道子类是什么).
  • 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).

Writing - 鉴于上述可能的分配,您可以将什么类型的对象添加到 List foo3所有人> 以上可能的 ArrayList 赋值:

Writing - Given the above possible assignments, what type of object could you add to List foo3 that would be legal for all the above possible ArrayList assignments:

  • 您可以添加 Integer,因为在上述任何列表中都允许使用 Integer.
  • 您可以添加 Integer 子类的实例,因为上述任何列表中都允许 Integer 子类的实例.
  • 您不能添加 Double,因为 foo3 可能指向 ArrayList.
  • 您不能添加 Number,因为 foo3 可能指向 ArrayList.
  • 您不能添加 Object,因为 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

记住PECS:生产者.

  • Producer - 如果您需要一个 List 来生成 T 值(您想阅读 Ts 从列表中),你需要用 声明它?,例如列表.但是您不能添加到此列表中.

  • "Producer - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? , e.g. List<? . But you cannot add to this list.

Consumer - 如果您需要一个 List 来使用 T 值(您想编写 Ts 到列表中),你需要用 声明它吗?,例如列表.但是不能保证您可以从此列表中读取什么类型的对象.

"Consumer - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? , e.g. List<? . But there are no guarantees what type of object you may read from this list.

如果您需要读取和写入列表,则需要完全声明它,不要使用通配符,例如List.

If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g. List<Integer>.

注意 Java 泛型常见问题解答中的这个示例.注意源列表src(生产列表)如何使用,目标列表dest(消费列表)如何使用:

Note this example from the Java Generics FAQ. Note how the source list src (the producing list) uses , and the destination list dest (the consuming list) uses :

public class Collections { 
  public static <T> void copy(List<? 

另见

这篇关于&lt; 之间的区别?超级T>和 &lt;?