我有以下一段代码
public static <T extends Comparable<T>> T max(List<T> list){
Iterator<T> iter = list.iterator();
...
// code for finding the max element in the list
...
}
我的问题是,在这种情况下需要递归类型边界是什么?在我的理解中,T extends Comparable < T >
是指T
只能和T
本身比较。这是因为,Class 'T' implements Comparable<T>
等
class MyClass implements Comparable<MyClass>{
}
如果我错了,请随时纠正我。
那么现在来到实际的疑问,为什么我们需要指定< T extends Comparable < T > >
?无论如何,参数List<T>
列表将包含相同类型的元素。也就是说,假设我传递一个类型为List < MyClass2 >
的参数,那么所有的元素都将是相同的类型,即MyClass2
..
那么递归类型界的含义是什么?
为什么需要指定<T extends Comparable<T>>
?因为Comparable并不要求实现类与自身具有可比性。理论上可以写成
class Circle extends Shape implements Comparable<Integer> {
...
}
由于Comparable本身没有这个限制,所以在编写函数时必须在您的端进行此限制。然而,给定的边界比你需要的更严格。你可以打电话
public static <T extends Comparable<? super T>> T max(List<T> list) {
...
}
这意味着T
与它自己的某个超类相当。您需要这样做的原因在rgettman的Fruit示例中给出。T
仍然总是与自身具有可比性,但可比性并不一定要根据T
本身来定义。
您可能有一个强制子类为Comparable
到超类型的类层次结构。例如,您可以使用
class Fruit extends Comparable<Fruit>
所以每一块Fruit
都可以与另一块Fruit
相比较。然后是
class Apple extends Fruit ...
class Banana extends Fruit ...
每个子类都是Fruit
,所以它们都是Comparable<Fruit>
,而不是Comparable<Apple>
也不是Comparable<Banana>
。
这允许您在List<Apple>
中找到最大Fruit
(可能是一个坏例子,最大水果是什么?):
List<Apple> apples = getApples();
Fruit maximum = max(apples);
不需要是List<Fruit>
.
正如在评论中指出的那样,max
方法最好是:
public static <T extends Comparable<? super T>> T max(List<T> list){
使以下每一个都能工作:
List<Apple> apples = getApples();
Apple maxAppleOfApples = max(apples);
Fruit maxFruitOfApples = max(apples);
List<Banana> bananas = getBananas();
Banana maxBananaOfBananas = max(bananas);
Fruit maxFruitOfBananas = max(bananas);
List<Fruit> fruits = getFruit();
Fruit maxFruitOfFruit = max(fruits);