Explanation of generic

Actually, it means that T can implement Comparable<? super T>, not just Comparable<T>.

For example, it means that a Student class can implement Comparable<Person>, where Student is a subclass of Person:

public class Person {}

public class Student extends Person implements Comparable<Person> {
    @Override public int compareTo(Person that) {
        // ...
    }
}

In this case, a List can be sorted by Collections.sort() but only based on Person‘s properties, because you pass the Student instance into compareTo() as a Person (unless you downcast it, of course).

In practice however, you’ll never see a Student class implement Comparable<Person>. That’s because Person will probably have implemented Comparable<Person>, and Student inherits it implementation. The end result is the same however: you can pass a List<Student> to Collections.sort() and have it sorted on Person‘s properties.

The difference between Comparable<T> and Comparable<? super T> is more obvious in the overloaded version of Collections.sort() that takes a Comparator<? super T>:

class ByAgeAscending implements Comparator<Person> {
    @Override public int compare(Person a, Person b) {
        return a.getAge() < b.getAge();
    }
}

List<Student> students = getSomeStudents();
Collections.sort(students, new ByAgeAscending());

Leave a Comment