Java:关于Collections ReverseComparator的实现

shr*_*000 6 java collections comparator

这实现如下(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(); }
}
Run Code Online (Sandbox Code Playgroud)

为什么不能实现如下:

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);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

它只是风格,还是有更深层次的原因?

编辑:显示的源代码来自Sun/Oracle jdk((jdk1.6.0_31)).

Edw*_*rzo 1

我相信这一切都与使 ReverseComparator 成为单例对象的意图有关。由于单例实例必须在静态上下文中定义,因此使用任何泛型类型都是没有意义的。

static final ReverseComparator REVERSE_ORDER = new ReverseComparator();
Run Code Online (Sandbox Code Playgroud)

此代码生成原始类型警告。

因此,仅用于此问题的 ReverseComparator 的实现可以按照您的建议或实现。也许他们选择当前的实现是因为它更容易阅读,并且因为他们认为如果仅将其私人用于这个简单的目的,则不需要进一步的泛化。

在您的实现和 Oracle 的实现上运行 Java 反编译器会生成相同的原始类型字节代码。

 public int compare(java.lang.Comparable, java.lang.Comparable
 public int compare(java.lang.Object, java.lang.Object);
Run Code Online (Sandbox Code Playgroud)

最后,当方法中通过 Collections 类的公共接口暴露比较器时reverseOrder(),无法避免强制转换和未经检查的警告。但我们都确信,无论涉及何种类型,这都不会失败。

最重要的是,恕我直言,我认为实现它的唯一原因与代码清晰度有关,或者是希望在无论如何无法阻止未经检查的警告的情况下,不要使事情变得不必要的复杂化。但是,嘿,这不是我第一次错了;-)