2012-03-15 80 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'

所以在這種情況下,解決方案不是由數據結構決定的,而是由泛型決定的。