【问题标题】:How Generics at Class Level Parameter works [duplicate]类级别参数的泛型如何工作[重复]
【发布时间】:2013-07-19 23:39:05
【问题描述】:

考虑以下来自 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));
}

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

【问题讨论】:

标签: java generics


【解决方案1】:

没有将泛型类型传递给构造函数,所有类型都会被删除,编译器会看到这个选项

String glom ( Collection );

int glom ( List );

类型也从main中定义的strings变量中删除,所以它的类型是List

因为ListCollection 更具体,所以它选择int glom ( List )

现在,如果您指定了泛型参数,则不会发生类型擦除,并且编译器知道它无法将int glom ( List&lt;Integer&gt; ) 匹配到List&lt;String&gt;,因此它回退到String glom ( Collection&lt;?&gt; )

【讨论】:

    【解决方案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&lt;?&gt; objs ) 覆盖匹配调用(它传递了List&lt;String&gt;),而int glom(List &lt;Integer&gt; ints ) 不匹配,因为String 不是Integer

    【讨论】:

      【解决方案3】:

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

      This 表明您想要在字节码级别发生。

      【讨论】:

      • 这两个例子都在 Eclipse Kepler 中编译得很好。
      猜你喜欢
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-17
      • 1970-01-01
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多