2013-07-19 20 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