类级别参数的泛型如何工作

时间:2013-07-19 15:19:18

标签: java generics

考虑使用Java Puzzlers中的代码

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

}

当我运行这个程序时,它会给出类强制转换异常,但如果我在main方法中为Gloam类提供任何Generic参数,它就可以正常工作。

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

我不明白泛型如何在类类型参数中起作用?

3 个答案:

答案 0 :(得分:9)

如果没有传递给构造函数的泛型类型,则会删除所有类型,并为编译器提供此选项

String glom ( Collection );

int glom ( List );

该类型也会从strings中定义的main变量中删除,因此其类型为List

由于ListCollection更具体,因此选择int glom ( List )

现在,如果你已经指定了泛型参数,那么就不会发生类型擦除,并且编译器知道它不能与int glom ( List<Integer> )匹配到List<String>,所以它会回退到String glom ( Collection<?> )

答案 1 :(得分: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

答案 2 :(得分:0)

您可以使用泛型来区分Java中的方法。 JVM没有看到这种类型,但是如果参数或返回类型不同,它仍将在Sun / Oracle编译器中编译。这不会为IBM / eclipse编译器编译。

This显示您希望在字节代码级别发生。

相关问题