Differences between `copy(List<? super T> dest, List<? extends T> src) ` and `copy(List<T> dest, List<? extends T> src)`
我试图通过阅读以下内容来学习Java泛型通配符:http://www.angelikalanger.com/genericsfaq/faqsections/typearguments.html faq103
材料中有一个示例:
1 2 3 4 5 6 | public class Collections { public static <T> void copy (List<? super T> dest, List<? extends T> src) { for (int i=0; i<src.size(); i++) dest.set(i,src.get(i)); } } |
我想知道是否可以将方法签名更改为以下内容:
1 | public static <T> void copy(List<? super T> dest, List<? extends T> src) { |
号
γ
1 | public static <T> void copy(List<T> dest, List<? extends T> src) { |
这两种方法有什么不同吗?
我们将不胜感激。
正如马特·弗雷克在回答中指出的那样,两者之间没有太大的实际区别
1 2 | 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) |
号
下面的代码段包含一个
作者选择使用
在本例中,第一个列表是对象的使用者。它只接收来自另一个列表的对象。因此,它的类型应该是
然而,下面的代码片段也包含一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 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)); } } } |
你是对的。在这种情况下,两个参数的类型参数被用来表示
你也可以用另一种方式表达,即:
1 | List<? super T> dest, List<T> src |
达到同样的效果。
编辑:我怀疑作者要强调关于PECS原则的观点