2013-07-19 44 views
4

考慮從Java謎題下面的代碼如何仿製工作

class Gloam<T>{ 

String glom(Collection<?> objs) { 
    System.out.println("collection"); 
    String result = ""; 
    for (Object o : objs){ 
     result += o; 
    } 
    return result; 
} 

int glom(List <Integer> ints) { 
    System.out.println("List"); 
    int result = 0; 
    for (int i : ints) 
     result += i ; 
    return result; 
} 

public static void main(String[] args) { 
    List<String> strings = Arrays.asList("1", "2", "3"); 
    System.out.println(new Gloam().glom(strings)); 
} 

} 

當我運行這個程序,它提供了類轉換異常,但如果我提供的主要方法黃昏類的任何通用的說法,它工作正常。

public static void main(String[] args) { 
    List<String> strings = Arrays.asList("1", "2", "3"); 
    System.out.println(new Gloam<Date>().glom(strings)); 
} 

我不明白泛型如何在類類型參數中工作?

+0

什麼Java版本? –

+0

沒錯,我很確定它與類型擦除有關。 http://docs.oracle.com/javase/tutorial/java/generics/erasure.html – Sadbrute

+0

@AlexanderPogrebnyak Java 1.6 –

回答

9

由於沒有泛型類型傳遞到構造函數,所有類型被刪除,編譯呈現這個選擇

String glom (Collection); 

int glom (List); 

種類也從main定義strings變量刪除,因此,它的類型是List

因爲ListCollection更具體,所以它選擇int glom (List)

現在,如果你指定了泛型參數,則沒有類型擦除發生,編譯器知道它不能匹配int glom (List<Integer>)List<String>,所以它回落到String glom (Collection<?>)

0

您可以使用泛型來區分Java中的方法。 JVM沒有看到這種類型,但是如果參數或返回類型不同,它仍然可以在Sun/Oracle編譯器中編譯。這不適用於IBM/eclipse編譯器。

This顯示你想要的是在字節代碼級別發生。

+0

這兩個示例在Eclipse Kepler中編譯得都很好。 –

2

一旦您無法提供泛型類型參數,那麼編譯器就會忽略整個類的所有泛型類型。類本質上就變成了:

class Gloam<T> { 

    String glom(Collection objs) { 
    System.out.println("collection"); 
    String result = ""; 
    for (Object o : objs) { 
     result += o; 
    } 
    return result; 
    } 

    int glom(List ints) { 
    System.out.println("List"); 
    int result = 0; 
    for (int i : ints) 
     result += i; 
    return result; 
    } 

    public static void main(String[] args) { 
    List strings = Arrays.asList("1", "2", "3"); 
    System.out.println(new Gloam().glom(strings)); 
    } 

} 

所以,現在的編譯器會選擇int glom(List ints)覆蓋,因爲這是呼叫相匹配的最特定覆蓋。但它也會導致類拋出異常。當您提供泛型參數時,仿製藥將被保留並且String glom(Collection<?> objs)覆蓋與呼叫相匹配(通過List<String>),而int glom(List <Integer> ints)不匹配,因爲String不是Integer