e.g. The code below throws a ClassCastException when the second Object is added to the TreeSet. Couldn't TreeSet have been written so that the type parameter can only be a Comparable type? i.e. TreeSet would not compile because Object is not Comparable. That way generics actually do their job - of being typesafe.
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String [] args) {
TreeSet<Object> t = new TreeSet<Object>();
t.add(new Object());
t.add(new Object());
}
}
If the type would have to be Comparable, you couldn't create a TreeSet with a non-comparable type and a Comparator (which you can as it is now).
One way to fix this while still being type-safe would have been to have two classes: one with a comparable type parameter and one with a non-comparable type parameter and no default constructor (only the constructor that takes a Comparator), but I suppose the java devs didn't want to introduce two classes that basically did the same thing (though one could easily be implemented as a wrapper around the other).
Another (and arguably cleaner way) would be to extend the type system so that certain constructors only exist when used with certain type parameters (i.e. the default constructor only exists if the type parameter is comparable), but I suppose that would have made the generic system too complex for java.