I assume there are two questions here:
- Why the bounds
Object
is required
- Why to use
Comparable<? super T>
instead of Comparable<T>
.
For the first question, it is not really required to give explicit Object
bounds, but it may depend upon how you want the erasure of your method look like. With explicit Object
bound, your type parameter will be erased to Object
, and without that, it will be erased to Comparable
. Most of the time, you won't find any need to give explicit bound, but this may be required for API compatibility as already explained in this post.
As for second question, using Comparable<? super T>
is often a good idea, if you want to pass a list to List<T>
, where T
is comparable. Why? Suppose you have a class:
class Employee implements Comparable<Employee> { }
and a subclass:
class PartTimeEmployee extends Employee { }
and you want to pass a List<PartTimeEmployee>
to a List<T>
. It might seem straight-forward, and easy not before you realise that your PartTimeEmployee
doesn't really implement a Comparable<PartTimeEmployee>
but a Comparable<Employee>
. So, what you do is, change the bounds of T
to:
T extends Comparable<? super T>
.. and then you can pass a List<PartTimeEmployee>
, as it satisfies the bound now.
The reason why you've to do this is to do with, erasure (Again?). Yes. On first seeing that error, you might jump off your chair and quickly make PartTimeEmployee
comparable too by doing this:
class PartTimeEmployee extends Employee implements Comparable<PartTimeEmployee>
...but hey, you're doing wrong there. Java generics doesn't allow you to implement or extend from two different parameterized instantiation of same generic type. You're saying that, PartTimeEmployee
implement both Comparable<Employee>
and Comparable<PartTimeEmployee>
. With this, you would have two methods in your PartTimeEmployee
:
compareTo(PartTimeEmployee)
compareTo(Employee)
and after erasure, both of them will become:
compareTo(Object)
compareTo(Object)
and you've duplicate methods now. That is why it's illegal.
However in this case, since you have a List<? extends T>
as parameter type, I think you might well do with Comparable<T>
, because then when you pass a List<PartTimeEmployee>
, T
will be inferred as Employee
, and hence will satisfy the bound.