其实现方式如下(jdk1.6.0_31):
private static class ReverseComparator<T>
implements Comparator<Comparable<Object>>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare(Comparable<Object> c1, Comparable<Object> c2) {
return c2.compareTo(c1);
}
private Object readResolve() { return reverseOrder(); }
}为什么不能按如下方式实现:
private static class ReverseComparator<T extends Comparable<T>>
implements Comparator<T>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare(T c1, T c2){
return c2.compareTo(c1);
}
...
}这只是风格,还是有更深层次的原因?
编辑:显示的源代码来自Sun/Oracle jdk ((jdk1.6.0_31))。
发布于 2012-04-26 12:19:22
我相信这一切都与让ReverseComparator成为单一对象的意图有关。由于singlenton实例必须在静态上下文中定义,因此使用任何泛型类型都没有意义。
static final ReverseComparator REVERSE_ORDER = new ReverseComparator();此代码生成原始类型警告。
因此,仅用于此问题的ReverseComparator的实现可能与您的建议相同,也可能与实现时相同。也许他们选择当前的实现是因为它更容易阅读,而且他们认为如果只是为了这个简单的目的而私下使用它,那么就不需要进一步的泛化。
在您的实现和Oracle的实现上运行Java反编译器会生成相同的原始类型字节码。
public int compare(java.lang.Comparable, java.lang.Comparable
public int compare(java.lang.Object, java.lang.Object);最后,当通过reverseOrder()方法中的集合类的公共接口公开比较器时,不可能避免强制转换和未检查的警告。但我们都确信,无论涉及什么类型,这都不会失败。
归根结底,我认为它被实现的唯一原因是代码的清晰度,或者是希望在无论如何都无法防止未经检查的警告的情况下,不要让事情变得更加复杂。但是,嘿,这不是我第一次错了;-)
发布于 2012-04-25 16:42:04
只是猜测,但它存储在静态字段中
static final ReverseComparator REVERSE_ORDER
= new ReverseComparator();所以你的版本会生成一个“原始类型”警告。
发布于 2012-04-26 11:22:31
我正在查看Oracle 1.6.0_26,但我看到了相同的代码。据我所知,它们在功能上是等价的。您也可以像这样编写它:
private static class ReverseComparator<T> implements Comparator<Comparable<T>>, Serializable {
// use serialVersionUID from JDK 1.2.2 for interoperability
private static final long serialVersionUID = 7207038068494060240L;
public int compare( Comparable<T> c1, Comparable<T> c2 ) {
return c2.compareTo( (T) c1 );
}
private Object readResolve() {
return reverseOrder();
}
}关于他们为什么使用Comparable<Object>,我唯一的猜测是,实现Comparable (或Comparator)的类应该遵守equals()约定,该约定确实使用Object。因此,从语义上讲,这强调了这种联系。除此之外,我想不出一个原因。
https://stackoverflow.com/questions/10311155
复制相似问题