我可以将以下代码转换为使用泛型吗?
时间:2020-03-05 18:52:15 来源:igfitidea点击:
我将一个应用程序转换为使用Java 1.5,并且发现以下方法:
/** * Compare two Comparables, treat nulls as -infinity. * @param o1 * @param o2 * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2 */ protected static int nullCompare(Comparable o1, Comparable o2) { if (o1 == null) { if (o2 == null) { return 0; } else { return -1; } } else if (o2 == null) { return 1; } else { return o1.compareTo(o2); } }
理想情况下,我想使该方法采用两个相同类型的Comparables,是否可以将其转换以及如何转换?
我认为以下方法可以解决问题:
protected static <T extends Comparable> int nullCompare(T o1, T o2) {
但它未能摆脱IntelliJ中的警告,该警告是"未经检查的对compareTo(T)的调用,它是原始类型'java.lang.Comparable'的成员"。
return o1.compareTo(o2);
解决方案
回答
更改为:
protected static <T extends Comparable<T>> int nullCompare(T o1, T o2) {
我们需要这样做,因为Comparable本身就是一个泛型类型。
回答
这是一个奇怪的情况:
static class A { ... } static class B extends A implements Comparable<A> { public int compareTo(A o) { return ...; } }
幸运的是,上面的代码很少见,但是nullCompare()不支持B的比较,除非声明Comparable可以应用于T或者其任何超类:
protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {
即使大多数人永远不会从上述调整中受益,但在为导出的库设计API时,它可能会派上用场。
回答
我不确定泛化此方法是否有意义。目前,该方法适用于任何类型的Comparable;如果我们将其通用化,则必须多次实施(使用完全相同的代码)。有时可以比较两个没有共同祖先的对象,任何通用版本都不允许这样做。
通过添加泛型,我们不会为代码增加任何安全性;在对compareTo的调用中将发生任何安全问题。我建议的只是取消警告。并不是真正警告我们任何有用的东西。
回答
无法编辑,因此我必须发布我的答案。
由于Comparable是泛型的,因此我们需要声明嵌套的类型参数。
protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) {
请注意,可比<?超级T>,这使它更加灵活。我们将在Collections.sort上看到相同的方法定义
public static <T extends Comparable<? super T>> void sort(List<T> list) {
回答
为了使其更加通用,我们甚至可以允许它适用于两种不同的类型。 = P
/** * Compare two Comparables, treat nulls as -infinity. * @param o1 * @param o2 * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2 */ protected static <T> int nullCompare(Comparable<? super T> o1, T o2) { if (o1 == null) { if (o2 == null) { return 0; } else { return -1; } } else if (o2 == null) { return 1; } else { return o1.compareTo(o2); } }