让我们假设我们有以下代码:
class A {} class B extends A {} class C extends B {} public static <T> T testMe(List<? super T> list1,List<? extends T> list2) { return null; } public static void main(String[] args) { List<B> listB = new ArrayList<>(); List<C> listC = new ArrayList<>(); // All three variants are possible: A a=testMe(listB,listC); B b=testMe(listB,listC); C c=testMe(listB,listC); }
问题是关于公共静态< T> T testMe(List<?super T> list1,List<?extends T> list2).如果有三个类,编译器如何确定T类型:A,B,C,?当我分析Collections.copy时出现了这个问题.
解决方法
在所有3种情况下,编译器推断类型参数T的类型C.
most specific type符合约束条件.
[T]he inference algorithm tries to find the most specific type that works with all of the arguments.
对于前两个陈述,
A a = testMe(listB,listC); B b = testMe(listB,listC);
B和C都匹配,因为List< B>匹配列表<?超级B>和列表< C>匹配列表<?扩展B>和列表< B>匹配列表<?超级C>和列表< C>匹配列表<?扩展C>.编译器选择匹配的最具体类型,C. 您可以使用显式类型参数进行编译,以使编译器将其解析为B:
A a = Super.<B>testMe(listB,listC); B b = Super.<B>testMe(listB,listC);
在第三行中,只有C匹配,这就是编译器为T选择的内容.
C c = testMe(listB,listC);
发生这种情况是因为分配的变量是C类型,而B不能分配给C.