Java泛型:如何在没有原始类型的情况下转换为(T extends Comparable <? super T>)?

4

我想知道是否有可能将一个非Comparable类型转换成某个类型,以使其与方法参数T相匹配,而T具有模板类型<T extends Comparable<? super T>>,就像Collections.sort()方法一样。

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

假设我有一个非可比较对象列表的引用,并且想通过进行强制类型转换来调用该方法,代码如下:
List<E> foo = new List<E>(a);
Collections.sort( /* magic cast */ foo);

如果我强制转换为(List<? extends Comparable>),我可以做到这一点,但是这会生成一个警告,即我使用了原始类型(在这种情况下没有模板类型的Comparable)。假设我想避免使用原始类型,甚至通过@SuppressWarnings("rawtypes")来抑制它们(例如保留向后兼容性并避免使用原始类型)。
是否可能通过将其转换为(List<? extends Comparable</*something*/>>)来避免使用原始类型,那么“something”是什么(未经检查的转换是可以接受的)?
编辑:此示例只是为了说明这一点。实际上,我没有可比较的对象,也不想排序任何东西,但我只需要动态检查某些东西是否为某种类型(在本例中为Comparable)(通过instanceof),然后将某些参数传递给具有类似于Collections.sort()方法的模板参数的方法。

我可能有所误解,但是你正在尝试实现的目标似乎没有意义。如果E没有实现Comparable,那么尝试将这些对象列表传递给Collections.sort的意义在哪里?你肯定只会在运行时得到一个类转换异常吧? - Péter Török
如果它没有实现Comparable接口,你可以使用sort方法,该方法需要一个Comparator。 - Puce
@Peter:假设我想首先检查它是否是Comparable的实例,然后再进行强制转换。如果我想尽力对某些东西进行排序,这是有意义的。 - eold
@Puce:我并不是在尝试排序。这只是一个没有意义的简单例子,但在我的情况下,它是有意义的。 - eold
如果你的示例更有意义,也许你会得到更好的答案。 - Isaac Truett
显示剩余2条评论
3个回答

3
将其转换为
Collections.sort((List<Comparable<Object>>) list);

这不会产生“rawtype”警告,只会有一个“unchecked cast”警告(无论如何都会出现)。
从您在EDIT中提到的内容来看,您最终想做类似于这样的事情吗?
if(!list.isEmpty() && list.get(0) instanceof Comparable){
    List<Comparable<Object>> cmprList = (List<Comparable<Object>>)list;
    Collections.sort(cmprList);
}

由于您无法真正检查某个特定对象是否可与另一个特定对象进行比较(除非使用反射查看它们的compareTo方法,或者实际调用此compareTo方法),因此这似乎是实际上最好的可能性。 - Paŭlo Ebermann
如果在空列表上调用list.get(0) instanceof Comparable,将会抛出IndexOutOfBoundsException异常。 - Daniel
2
@Daniel 不,它按预期工作(在 Oracle JDK7 上进行了测试以防万一)。如果列表为空,则当列表为空时不会执行 list.get(0),因为 !list.isEmpty() 表达式将为 false,而 Java 中的 && 是惰性评估的。 - rodion
@rodion:我改正了——虽然不确定我是怎么错过那个的。 - Daniel

1

这将在Eclipse中编译:

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

您将会收到一个“类型安全性:未经检查”的警告,您可以使用以下代码来抑制它:
@SuppressWarnings("unchecked")

这将允许您调用sort函数。这是您要寻找的吗?当然,不能保证在运行时是安全的。


1

这是不可能的。 Collections.sort 需要 Comparable 接口才能调用 compareTo() 方法。那么在您的观点中,如果 sort 获取了一个非可比较对象的集合,应该发生什么?

也许您想使用类似于默认排序的东西,例如基于引用。但这样的东西并不存在隐式地。虽然它可以被实现。但我怀疑这是否是您想要的?那么为什么您想首先对列表进行排序呢?这些元素应该如何排序?


我其实不想排序。这只是一个大家都熟悉的例子,为了更容易地解释事情。 - eold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接