2012-03-15 62 views
4

运行的主要结果是:为什么不太匹配重载的方法被称为

"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

我相信这也应该是'方法(ArrayList的升)' – Kos 2012-03-15 08:07:42

回答

0

它将与第二个方法匹配即overloadedMethod(List<Number> o)如果你改变Number泛型类型?类似以下内容:

private void overloadedMethod(List<?> o) { 
    System.out.println("List<?>"); 
} 
5

由于lList,唯一的匹配函数是第一个。重载解析在编译时完成,而不是在运行时完成。没有考虑到l的值,只有它的类型。

至于语言而言,这很可能会成为:

List l = foo(); 
test.method(1); 

它不关心l有什么价值。

+0

请参考下面的意见我的帖子;还有更多的东西,甚至当我们把'l'改成'ArrayList '时也不起作用,因此这些类型看起来完全一样。 – Kos 2012-03-15 07:57:23

+0

@Kos:问题已更改,我的答案适用于问题的早期版本。 – 2012-03-15 08:03:52

3

overloadedMethod(ArrayList<Integer> o)不适合,因为已声明的参数l的类型为List而不是ArrayList并且未对动态类型执行重载。

overloadedMethod(List<Number> o)不适合,因为泛型类型参数不匹配。 Java不具有像C#这样的协变或逆变泛型,因此List<Number>List<Integer>不显示子类型关系。

因此,最好的过载是overloadedMethod(Collection<?> o),因为其他两个不匹配。

+0

我错了,我改变了代码。 应该有ArrayList l = new ArrayList ();结果是一样的。 – Yoda 2012-03-15 07:49:04

+0

嗯,你是对的,这是_is_可疑:),请编辑你的问题,以反映这个问题,让聪明的人比我会注意到真正的问题是 – Kos 2012-03-15 07:53:55

+0

备案:http://ideone.com/KUobo – Kos 2012-03-15 07:55:36

0

这种分辨率是在编译时执行的:

L型的是列表

但由于“T”是不相同的特定的“数量不能匹配到

列表&的ArrayList '和'Integer'

它只能被匹配到另一个泛型类型'?'和一个超级类'Collection'

所以在这种情况下,解决方案不是由数据结构决定的,而是由泛型决定的。