Java generics: How to cast to (T extends Comparable<? super T>) without raw-types

8.1k views Asked by At

I wonder whether it is possible to cast a non-Comparable to something so that it matches the method parameter T which has template type <T extends Comparable<? super T>>, like the Collections.sort() method

public static <T extends Comparable<? super T>> void sort(List<T> list)

Suppose I somewhere have a reference to list of non-Comparables and want to invoke that method by casting like this:

List<E> foo = new List<E>(a);
Collections.sort( /* magic cast */ foo);

I can do this if I cast to (List<? extends Comparable>), but this generates a warning that I am using raw-types (Comparable without template types in this case). Let's say I want to avoid using raw-types or even suppressing them via @SuppressWarnings("rawtypes") (e.g. to preserve backward compatibility and avoiding raw-types).

Is it possible to avoid using raw types by casting to (List<? extends Comparable</*something*/>>) and what would it be that "something" (unchecked cast is acceptable)?

EDIT: This example is just to illustrate the point. Actually I do not have a Comparable nor do I want to sort anything, but I just need to dynamically check whether something is of some type (Comparable in this example) (via instanceof) and then pass some argument to a method which has template arguments similar to the Collections.sort() method.

3

There are 3 answers

4
rodion On BEST ANSWER

Cast it to

Collections.sort((List<Comparable<Object>>) list);

This will not give "rawtype" warnings. Just one "unchecked cast" warning (which you will get anyway.)

Judging from what you mentioned in the EDIT, ultimately you want to do something like this?

if(!list.isEmpty() && list.get(0) instanceof Comparable){
    List<Comparable<Object>> cmprList = (List<Comparable<Object>>)list;
    Collections.sort(cmprList);
}
1
jmg On

This is certainly not possible. Collections.sort requires the Comparable in order to call the compareTo() method. So in your oppinion, what should happen when sort get's a collection of non-comparable objects?

It might be that you want to use something like a default ordering, based on the references for example. But such a thing does not exist implicitly. Though, it can be implemented. But I doubt that this is what you want? So why do you want to sort the list in the first place? And how should these elements be sorted?

0
Isaac Truett On

This will compile in Eclipse:

List<?> foo = new ArrayList<Object>();
Collections.sort((List<Comparable>) foo);

You will get a "Type Safety: Unchecked" warning that you can suppress with this:

@SuppressWarnings("unchecked")

That will let you call sort. Is that what you're looking for? No guarantees it will be safe at run time, of course.