When you look at Java container classes, you can often see & lt; T extends Comparable<? super T>>, Feel very puzzled
We feel & lt; T extends Comparable< T>> As we know, t is the type that implements the comparable interface, so they can be compared
<? super T> If the table name type parameter needs to be a parent of T or T, then & lt; T extends Comparable<? super T>> What does it mean
The constraint on t is a subclass of comparable, and the constraint on generics in comparable is,?At least it is the parent of T, so it means t is?Subclass of
In a word, elements must be classes or their subclasses that implement the comparable interface. You can use the parent class method to compare subtypes elements
/**
* Created by wangbin10 on 2018/9/18.
* The elements in mySort2() list must be classes that implement the Comparable interface or its subclasses
* Java takes a type-erasing approach to implementing generics and constrains the upper and lower bounds of generics with the extends and super keywords.
* The extends keyword is used to determine the upper bound of a generic type. <A extends B> indicates class B or its subclasses.
* The super keyword is used to determine the lower bound of the generic type. <A super B> indicates class B or its parent class, all the way up to Object.? then is a wildcard.
* Thus, <T extends Comparable<?super T>> indicates the upper bound for classes that implement the Comparable interface, <?super T> then indicates that subclasses of classes that implement the Comparable interface are also possible, thus determining the lower bound
*/
public class Test {
public static void main(String[] args) {
List<Animal> animals = new ArrayList<>();
animals.add(new Animal(25));
animals.add(new Dog(34));
mySort1(animals);//ok
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog(18));
dogs.add(new Dog(19));
/**
* This compilation can't pass, because T inferred is Animal, the result is Dog, Dog does not implement Comparable, so it can't
* mySort1(dogs);
* */
mySort2(animals);//ok
mySort2(dogs);//ok
}
/**
* The type parameter of mySort1 is T extends Comparable<T>, who requires that T must implement Comparable
* @param list
* @param <T>
*/
public static <T extends Comparable<T>> void mySort1(List<T> list) {
Collections.sort(list);
System.out.println("mySort1 Success!");
}
/**
* The elements in the list must be classes that implement the Comparable interface or its subclasses
* @param list
* @param <T>
*/
public static <T extends Comparable<?super T>> void mySort2(List<T> list) {
Collections.sort(list);
System.out.println("mySort2 Success!");
}
}
class Animal implements Comparable<Animal> {
int age;
public Animal(int age) {
this.age = age;
}
@Override
public int compareTo(Animal o) {
return Integer.compare(this.age, o.age);
}
}
/**
* Dog simply cannot implement Comparable<Dog>, because that would implement two identical interfaces
*/
class Dog extends Animal {
public Dog(int age) {
super(age);
}
}