The difference is that in the first case, a parameter of type T must be comparable with itself, while in the second case T can be comparable with anything. Typically, when the class C is comparable, it is declared that it implements Comparable<C> in any case. However, here is an example of when the first will not work, but the second will be:
class C1<T extends Comparable<T>> { // first case } class C2<T extends Comparable> { // second case } class A { // some super class } class B extends A implements Comparable<A> { // comparable to super class @Override public int compareTo(A o) { return 0; } }
Now:
new C1<B>(); // error new C2<B>(); // works
In general, you should never use the second approach; Try to stay away from raw types whenever possible. Also note that even the best option for the second approach would be
public class Something<T extends Comparable<? super T>> { }
Using this parameter with C1 would also compile the string new C1<B>() .
source share