我正在阅读书籍Java Generics and Collections作者:Maurice Naftalin,Philip Wadler,在前两章中,我的头脑中充满了怀疑。我无法弄清楚答案。
在电话中:
public static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
}
List<Object> objs = Arrays.<Object>asList(2, 3.14, "four");
List<Integer> ints = Arrays.asList(5, 6);
Collections.copy(objs, ints);
assert objs.toString().equals("[5, 6, four]");
在调用“复制”功能期间:
第一个参数:?=对象
第二个参数:?=整数
但是T的数据类型是什么? jvm如何基于擦除实现来决定?
在书中说:在 Collections.copy(obj,ints)行中,类型参数T被认为是Number。允许调用,因为 objs 具有List&lt; Object&gt;类型,这是List&lt ;?的子类型超级数字&gt; (因为Object是超类所需的数字的超类型)而整数具有类型List&lt; Integer&gt;,这是List&lt ;?的子类型extends Number&gt; (因为Integer是Number的子类型,因为extends通配符需要)。
但是,由于Integer实现了Serializable和Comparable两者,因此扩展Number类的aprt和Object类也是Serializable和Comparable的超类型。
那么为什么不将T视为可序列化或可比较而不是数字,因为替换原则将允许它被采用。
提前谢谢。
答案 0 :(得分:3)
http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
从“简单”示例中,JLS表示它选择满足其生成的所有约束的最具体类型。
15.12.2.7根据实际参数推断类型参数
超类型约束T:&gt; X暗示解决方案是其中之一 X的超类型。鉴于对T的几个这样的约束,我们可以相交 每个约束所暗示的超类型集合,因为 type参数必须是所有这些的成员。然后我们可以选择 交叉点中最具体的类型
Copy.java:11: incompatible types
found : java.lang.Integer[]
required: java.lang.String[]
String[] res = copy(Arrays.<Object>asList(2, 3.14, "four"), Arrays.asList(5, 6));
^
1 error
➜ /tmp cat Copy.java
import java.util.*;
public class Copy {
public static <T> T[] copy(List<? super T> dst, List<? extends T> src) {
for (int i = 0; i < src.size(); i++) {
dst.set(i, src.get(i));
}
return null;
}
public static void main(String[] args) {
String[] res = copy(Arrays.<Object>asList(2, 3.14, "four"), Arrays.asList(5, 6));
}
}
答案 1 :(得分:1)
T是根据参数决定的,但也可以明确指定。所以,是的,它可以是Comparable和Serializable。
所有这些都是有效的:
Collections.<Number>copy(objs, ints);
Collections.<Comparable>copy(objs, ints);
Collections.<Serializable>copy(objs, ints);
Collections.<Integer>copy(objs, ints);
Collections.copy(objs, ints); // implicitly Integer
如果未指定类型,则会选择整数,因为java documentation
中处理<? extends Integer>
的方式已得到解释
答案 2 :(得分:-1)
对象类是Serializable和Comparable的超类型
这不是真的,Serializable和Comparable是接口,与Object没有关系。
此外,super ?
与extends ?
完全相反
这意味着它不能应用于接口。它可以应用于接口。
当你写? extends T
时,它意味着?
is an unknown subtype of T
, probably T
itself。我相信JVM解决了T自下而上,这意味着T
实际上是Integer
而不是Number
(如果我错了,请纠正我)。
然后
Collections.copy(objs, ints)
实际上是
Collections.<Integer>(objs, ints)