4

考虑遵循 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 类提供任何通用参数,它就可以正常工作。

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

我不明白泛型在类类型参数中的工作原理?

4

3 回答 3

9

With no generic type passed into constructor, all types are erased and the compiler is presented with this choices

String glom ( Collection );

int glom ( List );

The type is also erased from strings variable defined in main, so its type is List.

Because List is more specific than Collection it chooses int glom ( List ).

Now, if you have specified the generic parameter, then no type erasure happens, and compiler knows that it cannot match int glom ( List<Integer> ) to List<String>, so it falls back to String glom ( Collection<?> )

于 2013-07-19T15:35:52.497 回答
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));
  }

}

So now the compiler will choose the int glom(List ints) override since that's the most-specific override that matches the call. But it will also result in the class cast exception. When you supply the generic parameter, generics are retained and the String glom(Collection<?> objs ) override matches the call (which is passing a List<String>), whereas int glom(List <Integer> ints ) does not match because String is not Integer.

于 2013-07-19T15:33:29.563 回答
0

您可以使用泛型来区分 Java 中的方法。JVM 看不到这种类型,但只要参数或返回类型不同,它仍将在 Sun/Oracle 编译器中编译。这不适用于 IBM/eclipse 编译器。

表明您希望发生在字节码级别。

于 2013-07-19T15:29:27.653 回答