关于java:类型参数的数据类型如何在协方差和逆变量中决定?

How is the datatype of type parameter decided in covariance and contravariance?

我在读Maurice Naftalin、Philip Wadler的《爪哇泛泛型》和《收藏》,在前两章里,我的脑海中充满了疑惑。我想不出答案。

通话中:

1
2
3
4
5
6
7
8
9
10
11
 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]");

在调用函数"copy"期间:第一个参数:?=对象第二个参数:?=整数

但是t的数据类型是什么?JVM如何根据擦除实现来决定它?

书中说:在collections.copy(obj,ints)行中,类型参数t取数字。允许调用,因为objs具有类型list,它是list<&63;super number>的子类型(因为object是数字的父类型,super需要),而ints具有类型list,它是list<&63;extends number>的子类型(因为integer是数字的子类型,扩展通配符需要)。

但由于integer实现了可序列化和可比较性,因此从扩展数字类到对象类的aprt也是可序列化和可比较的超级类型。所以为什么不把T看作是可序列化的或可比较的,而不是数字,因为替换原则允许它被采用。事先谢谢。


http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf

从"简单"的例子中,jls说它选择了最具体的类型,满足它生成的所有约束。

15.12.2.7根据实际参数推断类型参数

A supertype constraint T :> X implies that the solution is one of
supertypes of X. Given several such constraints on T, we can intersect
the sets of supertypes implied by each of the constraints, since the
type parameter must be a member of all of them. We can then choose the
most specific type that is in the intersection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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));
  }

}


T是根据参数决定的,但也可以显式指定。所以,是的,它可以进行比较和序列化。

所有这些都是有效的:

1
2
3
4
5
6
     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文档中处理和解释EDCOX1 9的方式,所以选择了整数。


对象类是可序列化的超类型,也可比较这不是真的,可序列化和可比较的是接口,与对象没有关系。

另外,super ?extends ?与strike>这意味着它不能应用于接口。.它可以应用于接口。

当你写? extends T时,它意味着?T的未知子类型,可能是T本身。我相信JVM的解决方案是自下而上的,这意味着T实际上是Integer而不是Number(如果我错了,请纠正我)。

然后

1
   Collections.copy(objs, ints)

事实上

1
   Collections.<Integer>(objs, ints)