类型参数的数据类型如何在协方差和逆变量中确定?
我正在阅读书籍Java Generics and Collections作者:Maurice Naftalin,Philip Wadler,在前两章中,我的头脑中充满了怀疑。 我无法弄清楚答案。
在通话中:
public static void copy(List dst, List src) { for (int i = 0; i < src.size(); i++) { dst.set(i, src.get(i)); } } List objs = Arrays.asList(2, 3.14, "four"); List ints = Arrays.asList(5, 6); Collections.copy(objs, ints); assert objs.toString().equals("[5, 6, four]");
在调用函数’copy’期间:
第一个参数:?=对象
第二个参数:?=整数
但是T的数据类型是什么? 基于擦除实现的jvm是如何决定的?
书中说:在Collections.copy(obj,ints)行中 ,类型参数T被认为是Number。 允许调用,因为objs的类型为List ,它是List (因为Object是超类所需的Number的超类型),而int的类型为List ,它是List (因为Integer是Number的子类型,如扩展通配符所要求的)。
但是由于Integer实现了Serializable和Comparable两者,因此扩展Number类和Object类的aprt也是Serializable和Comparable的超类型。
那么为什么不将T视为Serializable或Comparable而不是Number,因为Substitution Principle将允许它被采用。
提前致谢。
T是根据参数决定的,但也可以明确指定。 所以,是的,它可以是Comparable和Serializable。
所有这些都是有效的:
Collections.copy(objs, ints); Collections.copy(objs, ints); Collections.copy(objs, ints); Collections.copy(objs, ints); Collections.copy(objs, ints); // implicitly Integer
当没有指定类型时,由于 extends Integer>
extends Integer>
在java文档中处理和解释
http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf
从“简单”示例中,JLS表示它选择满足其生成的所有约束的最具体类型。
15.12.2.7根据实际参数推断类型参数
超类型约束T:> X意味着解决方案是X的超类型之一。在T上给出了几个这样的约束,我们可以交叉每个约束隐含的超类型集合,因为类型参数必须是所有约束的成员。他们。 然后我们可以选择交叉点中最具体的类型
Copy.java:11: incompatible types found : java.lang.Integer[] required: java.lang.String[] String[] res = copy(Arrays.
Object类也是Serializable和Comparable的超类型
事实并非如此,Serializable和Comparable是接口,与Object无关。
另外super ?
是extends ?
的确切倒数extends ?
这意味着它不能应用于接口。 它可以应用于接口。
你写的时候? extends T
? extends T
意味着?
是一个未知的T
亚型,可能是T
本身 。 我相信JVM解决了T自下而上,这意味着T
实际上是Integer
而不是Number
(如果我错了,请纠正我)。
然后
Collections.copy(objs, ints)
实际上是
Collections.(objs, ints)