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

推測するだけですが、静的フィールドに保存されます

static final ReverseComparator REVERSE_ORDER
            = new ReverseComparator();

そのため、ご使用のバージョンでは「rawtypes」警告が生成されます。

于 2012-04-25T08:42:03.853 に答える
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>があるという事実に基づいてます。したがって、意味的には、これはその接続を強調します。それ以外は理由が思いつかない。ComparableComparatorequals()Object

于 2012-04-26T03:22:31.090 に答える
1

それはすべて、ReverseComparatorをシングルトンオブジェクトにする意図に関連していると思います。シングルトンインスタンスは静的コンテキストで定義する必要があるため、ジェネリック型を使用しても意味がありません。

static final ReverseComparator REVERSE_ORDER = new ReverseComparator();

このコードは、rawタイプの警告を生成します。

そのため、この問題にのみ使用されるReverseComparatorの実装は、あなたが提案したとおり、または実装されたとおりであった可能性があります。おそらく、現在の実装を選択したのは、読みやすく、この単純な目的でのみ個人的に使用する場合は、さらに一般化する必要はないと考えたためです。

実装とOracleの実装でJavaデコンパイラを実行すると、同じraw型のバイトコードが生成されます。

 public int compare(java.lang.Comparable, java.lang.Comparable
 public int compare(java.lang.Object, java.lang.Object);

最後に、コンパレータがreverseOrder()メソッドのCollectionsクラスのパブリックインターフェイスを介して公開されている場合、キャストとチェックされていない警告を回避することはできません。しかし、関係するタイプに関係なく、これが失敗することはないと私たちは皆確信しています。

結論として、私見それが実装された唯一の理由は、コードの明確さ、またはとにかくチェックされていない警告を防ぐことができなかった場合に必要以上に物事を複雑にしないという願望に関係していると思います。しかしねえ、これは私が間違っているのは初めてではないでしょう;-)

于 2012-04-26T04:19:22.117 に答える