通用边界与通用类型的接口

时间:2013-02-05 10:11:40

标签: java generics

考虑以下代码

/**
 * Generic method with bounds
 */
public static <T> int countGreaterThan(Comparable<T>[] anArray,
        T elem) {
    int count = 0;
    for (Comparable<T> e : anArray)
        if (e.compareTo(elem) > 0)
            ++count;
    return count;
}
/**
 * Alternative to above
 */
public static <T extends Comparable<T>> int countGreaterThan(T[] anArray, T elem) {
    int count = 0;
    for (T e : anArray)
        if (e.compareTo(elem) > 0)
            ++count;
    return count;
}

看起来两者在功能上是相同的。然而,它们可能出现在同一个类中,显然会相互超载。当我使用以下代码时,似乎第二个方法被调用。如果没有第二个重载方法,则调用第一个方法。有人可以提供深入的解释吗?

    Integer[] array = new Integer[10];
    for (int i = 0; i < array.length; ++i)
        array[i] = i;

    System.out.println("Count > 5 = " + countGreaterThan(array, 5));

3 个答案:

答案 0 :(得分:2)

嗯,这不是彻底的删除。

第一种方法

<T> int countGreaterThan(Comparable<T>[] anArray,T elem)

适用于Comparable<T>的数组,但不强制要求elem也是Comparable

您可以查看:

static class Y {
   int val;
   public Y(int val){
      this.val=val;
   }
} 

static class W extends Y implements Comparable<Y>{
   public W(int val){
      super(val);
   }
   public int compareTo(Y o){
      return this.val-o.val;
   } 
}

W[] array = new W[10];
for (int i = 0; i < array.length; ++i)
    array[i] = new W(i);

System.out.println("Count > 5 = " + countGreaterThan(array, new Y(5)));       

将调用第一个方法。

答案 1 :(得分:1)

(它们可以出现在同一个类中,因为它们没有相同的擦除。第一个有第一个类型为Comparable[]的参数,第二个类型为Object[]。)

这两种方法都适用;在Java中,调用方法是在编译时确定的,并且始终是基于参数的引用类型的更具体的重载。

Carlo Pellegrini提出了一个很好的观点,即第一个被称为任何旧的Comparable。更多的专家可以纠正我,但我相当肯定这是由于拳击。您的示例中的调用首先将Integer[]绑定到T[],然后这会导致intT的装箱,现在称为Integer。对于他的示例Y,它只能匹配第一个。

答案 2 :(得分:0)

那是因为在Java中,Integer[]也是Comparable[]。如果您使用相同的方法将列表而不是数组作为参数,则它将无法以相同的方式工作,因为List<Integer>不是List<Comparable>。所以只有第二个版本会接受List<Integer>作为参数。

集合更加类型安全,并且使用泛型比数组更好。一般来说,你应该更喜欢它们而不是数组。