2

考虑以下代码

/**
 * 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));
4

3 回答 3

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

第一个方法将被调用。

于 2013-02-05T10:43:50.440 回答
1

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

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

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

于 2013-02-05T11:39:32.783 回答
0

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

集合比数组更具有类型安全性,并且与泛型一起使用更好。一般来说,您应该更喜欢它们而不是数组。

于 2013-02-05T10:29:28.967 回答