6

这实现如下(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))。

4

3 回答 3

1

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

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

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

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

于 2012-04-26T04:19:22.117 回答
1

我正在查看 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. 所以从语义上讲,这强调了这种联系。除此之外,我想不出理由。

于 2012-04-26T03:22:31.090 回答
1

只是猜测,但它存储在静态字段中

static final ReverseComparator REVERSE_ORDER
            = new ReverseComparator();

因此您的版本会生成“原始类型”警告。

于 2012-04-25T08:42:03.853 回答