为什么调用匹配较少的重载方法

时间:2012-03-15 07:41:42

标签: java overloading

运行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);
}
}

4 个答案:

答案 0 :(得分:5)

由于lList,唯一匹配的函数是第一个。重载分辨率在编译时完成,而不是在运行时完成。不考虑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<?>");
}