作为matt freake pointed out in his answer,实际区别不大
public static <T> void copyA(List<? super T> dest, List<? extends T> src) // and
public static <T> void copyB(List< T> dest, List<? extends T> src)
下面的 sn-p 包含一个exampleShowingThatTheyAreBasicallyEquivalent。
作者之所以选择使用? super T,很可能是想强调PECS principle: Producer extends - Consumer super。
在本例中,第一个列表是对象的消费者。它只接收来自另一个列表的对象。因此,它的类型应该是List<? super T>。
然而,下面的 sn-p 也包含一个 exampleShowingOneSubtleDifference。我几乎想不出一个真正实际相关的情况相关,但只是指出:当你规避类型时推理,并将类型<T> 固定到一个特定类型,您仍然可以将List<? super T> 作为第一个方法的第一个参数传递。在第二个中,类型必须完全匹配 - 但这只是方法签名所说的,所以也许很明显......
import java.util.List;
public class PecsExample
{
public static void exampleShowingOneSubtleDifference()
{
List<? super Number> superNumbers = null;
List<Number> numbers = null;
PecsExample.<Number>copyA(superNumbers, numbers); // Works
//PecsExample.<Number>copyB(superNumbers, numbers); // Does not work
}
public static void exampleShowingThatTheyAreBasicallyEquivalent()
{
List<? super Object> superObjects = null;
List<? super Number> superNumbers = null;
List<? super Integer> superIntegers = null;
List<Object> objects = null;
List<Number> numbers = null;
List<Integer> integers = null;
List<? extends Object> extendsObjects = null;
List<? extends Number> extendsNumbers = null;
List<? extends Integer> 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 <T> void copyA(List<? super T> dest, List<? extends T> src)
{
for (int i = 0; i < src.size(); i++)
{
dest.set(i, src.get(i));
}
}
public static <T> void copyB(List<T> dest, List<? extends T> src)
{
for (int i = 0; i < src.size(); i++)
{
dest.set(i, src.get(i));
}
}
}