考虑以下代码
/**
* 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));
答案 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[]
,然后这会导致int
到T
的装箱,现在称为Integer
。对于他的示例Y
,它只能匹配第一个。
答案 2 :(得分:0)
那是因为在Java中,Integer[]
也是Comparable[]
。如果您使用相同的方法将列表而不是数组作为参数,则它将无法以相同的方式工作,因为List<Integer>
不是List<Comparable>
。所以只有第二个版本会接受List<Integer>
作为参数。
集合更加类型安全,并且使用泛型比数组更好。一般来说,你应该更喜欢它们而不是数组。