显式类型参数
Explicit type parameter
正在阅读 Java Generics and Collections
本书。
//given
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
....
}
现在,它说 - We could also declare the above method with several possible signatures.
public static <T> void copy(List<T> dst, List<T> src) 1
public static <T> void copy(List<T> dst, List<? extends T> src) 2
public static <T> void copy(List<? super T> dst, List<T> src) 3
public static <T> void copy(List<? super T> dst, List<? extends T> src) 4
第一个限制太多,因为它只允许在目标和源具有完全相同的类型时调用 (understood
)。
其余三个对于使用隐式类型参数的调用是等效的(understood
- 类型推断算法将推断出适当的类型),
Confusing part -
但对于显式类型参数不同。
对于上面的示例调用,第二个签名仅在类型参数为 Object
时有效,第三个签名仅在类型参数为 Integer
.
时有效
因为我的尝试(下)而感到困惑
public class AsList {
public static void main (String...a) {
List<Number> l4 = new ArrayList<Number>();
List<Object> l5 = new ArrayList<Object>();
List<Integer> l6 = new ArrayList<Integer>();
//type is inferred implicitly for the below call
copy(l4, Arrays.<Integer>asList(1, 2, 3));
//type is specified explicitly
AsList.<Number>copy(l4, Arrays.<Integer>asList(1, 2, 3)); \why? 5
AsList.<Object>copy(l5, Arrays.<Integer>asList(1, 2, 3)); 6
AsList.<Integer>copy(l6, Arrays.<Integer>asList(1, 2, 3)); \why? 7
}
public static <T> void copy(List<T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.add(src.get(i));
}
}
}
这里,根据 Confusing part
只有语句 6
应该执行,但 5
和 7
也在工作。为什么?
编辑
Confusing part
中提到的示例调用如下
Collections.copy(objs, ints);
Collections.<Object>copy(objs, ints);
Collections.<Number>copy(objs, ints);
Collections.<Integer>copy(objs, ints);
在情况 5 中,形式参数是 List<Number>
和 List<? extends Number>
。传入 List<Number>
和 List<Integer>
完全没问题。
在案例 7 中,形式参数是 List<Integer>
和 List<? extends Integer>
。再次传入 List<Integer>
和 List<Integer>
就可以了。
正在阅读 Java Generics and Collections
本书。
//given
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
....
}
现在,它说 - We could also declare the above method with several possible signatures.
public static <T> void copy(List<T> dst, List<T> src) 1
public static <T> void copy(List<T> dst, List<? extends T> src) 2
public static <T> void copy(List<? super T> dst, List<T> src) 3
public static <T> void copy(List<? super T> dst, List<? extends T> src) 4
第一个限制太多,因为它只允许在目标和源具有完全相同的类型时调用 (understood
)。
其余三个对于使用隐式类型参数的调用是等效的(understood
- 类型推断算法将推断出适当的类型),
Confusing part -
但对于显式类型参数不同。
对于上面的示例调用,第二个签名仅在类型参数为 Object
时有效,第三个签名仅在类型参数为 Integer
.
因为我的尝试(下)而感到困惑
public class AsList {
public static void main (String...a) {
List<Number> l4 = new ArrayList<Number>();
List<Object> l5 = new ArrayList<Object>();
List<Integer> l6 = new ArrayList<Integer>();
//type is inferred implicitly for the below call
copy(l4, Arrays.<Integer>asList(1, 2, 3));
//type is specified explicitly
AsList.<Number>copy(l4, Arrays.<Integer>asList(1, 2, 3)); \why? 5
AsList.<Object>copy(l5, Arrays.<Integer>asList(1, 2, 3)); 6
AsList.<Integer>copy(l6, Arrays.<Integer>asList(1, 2, 3)); \why? 7
}
public static <T> void copy(List<T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.add(src.get(i));
}
}
}
这里,根据 Confusing part
只有语句 6
应该执行,但 5
和 7
也在工作。为什么?
编辑
Confusing part
中提到的示例调用如下
Collections.copy(objs, ints);
Collections.<Object>copy(objs, ints);
Collections.<Number>copy(objs, ints);
Collections.<Integer>copy(objs, ints);
在情况 5 中,形式参数是 List<Number>
和 List<? extends Number>
。传入 List<Number>
和 List<Integer>
完全没问题。
在案例 7 中,形式参数是 List<Integer>
和 List<? extends Integer>
。再次传入 List<Integer>
和 List<Integer>
就可以了。