运行main的结果是:
"Collection<?>".
为什么不使用ArrayList<Integer>
参数调用方法?
import java.util.*;
public final class GenericClass<T> {
private void overloadedMethod(Collection<?> o) {
System.out.println("Collection<?>");
}
private void overloadedMethod(List<Number> o) {
System.out.println("List<Number>");
}
private void overloadedMethod(ArrayList<Integer> o) {
System.out.println("ArrayList<Integer>");
}
public void method(List<T> l) {
overloadedMethod(l);
}
public static void main(String[] args) {
GenericClass<Integer> test = new GenericClass<Integer>();
ArrayList l = new ArrayList<Integer>();
test.method(l);
}
}
答案 0 :(得分:5)
由于l
是List
,唯一匹配的函数是第一个。重载分辨率在编译时完成,而不是在运行时完成。不考虑l
的值,只考虑其类型。
就语言而言,这可能也是:
List l = foo();
test.method(1);
它不关心l
的价值。
答案 1 :(得分:3)
overloadedMethod(ArrayList<Integer> o)
不合适,因为声明的参数l
类型为List
而不是ArrayList
,并且就动态类型而言,未完成重载
overloadedMethod(List<Number> o)
也不合适,因为通用类型参数不匹配。 Java没有像C#这样的协变或逆变泛型,因此List<Number>
和List<Integer>
不会表现出子类型关系。
因此,最好的超载是overloadedMethod(Collection<?> o)
,因为其他两个不匹配。
答案 2 :(得分:0)
此解决方案在编译时执行:
l的类型是List
但无法与
匹配列表&amp; ArrayList,因为'T'与特定'Number'和'Integer'
不同它只能匹配另一个通用类型'?'和超级'收藏'
因此在这种情况下,分辨率不是由数据结构决定的,而是由泛型决定的。
答案 3 :(得分:0)
如果您将overloadedMethod(List<Number> o)
更改为通用类型Number
,它将与第二种方法匹配,即?
,如下所示:
private void overloadedMethod(List<?> o) {
System.out.println("List<?>");
}