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

eold picture eold · Feb 16, 2011 · Viewed 7.9k times · Source

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.

Answer

rodion picture rodion · Feb 16, 2011

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);
}