`copy(List dest,List src)`和`copy(List dest,List src)之间的区别

我正在尝试通过阅读以下内容来学习Java Generics通配符: http : //www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ103

材料中有一个例子:

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)); } } 

我想知道我是否可以更改方法签名如下:

  public static  void copy(List dest, List src) { 

  public static  void copy(List dest, List src) { 

这两种方法之间有什么区别吗?

例子将不胜感激。

你是对的。 在这种情况下,两个参数的Type Arguments用于表示dest必须包含src中超类型对象的对象的关系。 因此,如果你说src包含 那么就足以说dest包含T的对象了。

你也可以反过来表达它,即:

 List dest, List src 

达到同样的效果。

编辑:我怀疑作者强调了关于PECS原则的观点

正如亚特弗里克在他的回答中指出的那样,两者之间没有太大的实际区别

 public static  void copyA(List dest, List src) // and public static  void copyB(List< T> dest, List src) 

下面的代码片段包含一个exampleShowingThatTheyAreBasicallyEquivalent

作者选择使用的原因是? super T ? super T最有可能是他们想要强调PECS原则:生产者extends – 消费者super

在此示例中,第一个列表是对象的使用者 。 它只接收来自其他列表的对象。 因此,它的类型应该是List List

但是,下面的代码片段还包含一个exampleShowingOneSubtleDifference 。我几乎不会想到这实际上是相关的情况 ,只是指出它:当你绕过类型推断,并将类型到一个特定类型时,你仍然可以传入一个List List作为第一种方法的第一个参数。 在第二个中,类型必须完全匹配 – 但这只是方法签名所说的,所以也许它显而易见……

 import java.util.List; public class PecsExample { public static void exampleShowingOneSubtleDifference() { List superNumbers = null; List numbers = null; PecsExample.copyA(superNumbers, numbers); // Works //PecsExample.copyB(superNumbers, numbers); // Does not work } public static void exampleShowingThatTheyAreBasicallyEquivalent() { List superObjects = null; List superNumbers = null; List superIntegers = null; List objects = null; List numbers = null; List integers = null; List extendsObjects = null; List extendsNumbers = null; List extendsIntegers = null; copyA(objects, objects); copyA(objects, numbers); copyA(objects, integers); copyA(numbers, numbers); copyA(numbers, integers); copyA(integers, integers); copyA(superObjects, objects); copyA(superObjects, numbers); copyA(superObjects, integers); copyA(superNumbers, numbers); copyA(superNumbers, integers); copyA(superIntegers, integers); copyA(objects, extendsObjects); copyA(objects, extendsNumbers); copyA(objects, extendsIntegers); copyA(numbers, extendsNumbers); copyA(numbers, extendsIntegers); copyA(integers, extendsIntegers); copyB(objects, objects); copyB(objects, numbers); copyB(objects, integers); copyB(numbers, numbers); copyB(numbers, integers); copyB(integers, integers); copyB(superObjects, objects); copyB(superObjects, numbers); copyB(superObjects, integers); copyB(superNumbers, numbers); copyB(superNumbers, integers); copyB(superIntegers, integers); copyB(objects, extendsObjects); copyB(objects, extendsNumbers); copyB(objects, extendsIntegers); copyB(numbers, extendsNumbers); copyB(numbers, extendsIntegers); copyB(integers, extendsIntegers); } public static  void copyA(List dest, List src) { for (int i = 0; i < src.size(); i++) { dest.set(i, src.get(i)); } } public static  void copyB(List dest, List src) { for (int i = 0; i < src.size(); i++) { dest.set(i, src.get(i)); } } }