17

2 つの s を使用する一般的な max 関数を作成しようとしていますComparable

これまでのところ、

public static <T extends Comparable<?>> T max(T a, T b) {
    if (a == null) {
        if (b == null) return a;
        else return b;
    }
    if (b == null)
        return a;
    return a.compareTo(b) > 0 ? a : b;
}

これはコンパイルに失敗します

The method compareTo(capture#5-of ?) in the type Comparable<capture#5-of ?> is not applicable for the arguments (T)

これが言っていると思うのは、?inComparable<?>がパラメーター a の 1 つのタイプとパラメーター b の別のタイプとして解釈される可能性があるため、それらを比較できないということです。

この穴から抜け出すにはどうすればいいですか?

4

5 に答える 5

29

最良の結果を得るには、を使用する必要がありますpublic static <T extends Comparable<? super T>> T max(T a, T b)

の問題<T extends Comparable<?>>は、これはタイプTがいくつかのタイプに匹敵することを示していますが、そのタイプが何であるかがわからないことです。もちろん、常識では、Comparableを実装するクラスは、少なくともそれ自体と比較できる(つまり、独自のタイプのオブジェクトと比較できる)必要がありますが、技術的には、クラスAの実装Comparable<B>を妨げるものはありません。とBは互いに何の関係もありません。<T extends Comparable<T>>この問題を解決します。

しかし、それには微妙な問題があります。クラスXがを実装しComparable<X>、Xを拡張するクラスYがあるとします。したがって、クラスYはComparable<X>継承によって自動的に実装されます。クラスYはComparable<Y>、異なるタイプパラメータを使用してインターフェイスを2回実装できないため、実装することもできません。YのインスタンスはXのインスタンスであるため、これは実際には問題ではありません。したがって、YはYのすべてのインスタンスに相当します。ただし、問題は、<T extends Comparable<T>> T max(T a, T b)Yがを実装していないため、関数でタイプYを使用できないことですComparable<Y>。境界が厳しすぎます。<T extends Comparable<? super T>>TがTのスーパータイプ(すべてのTインスタンスを含む)に匹敵するのに十分であるため、問題を修正します。この場合、ルールPECS(プロデューサーextends、コンシューマー)を思い出してください。superComparableはコンシューマー(比較するオブジェクトを取り込む)なのでsuper、理にかなっています。

これは、Javaライブラリのすべての並べ替えおよび順序付け関数で使用される型の境界です。

于 2011-06-24T10:53:37.153 に答える
4

このエラーが発生するのは、Comparable<?>基本的に、詳細のないものに匹敵すると言っているからです。代わりに記述する必要がありますComparable<T>。そうすれば、コンパイラは型 T がそれ自体に匹敵することを知ることができます。

于 2011-06-23T10:05:52.043 に答える
1

SO が生成した関連リンクから自分の質問に答える - これはFun with Java genericsの微妙な複製のようですが、タイトルが見つからないことで私を責めることはできないと思います!

最も簡単な解決策は

public static <T extends Comparable<T>> T max(T a, T b) {
    if (a == null) {
        if (b == null) return a;
        else return b;
    }
    if (b == null)
        return a;
    return a.compareTo(b) > 0 ? a : b;
}
于 2011-06-23T10:08:45.313 に答える
1

このためのユーティリティ クラスを作成しました。便利だと思うかもしれません (ライブラリはオープンソースです):

http://softsmithy.sourceforge.net/lib/docs/api/org/softsmithy/lib/util/Comparables.html

ホームページ:

http://www.softsmithy.org

ダウンロード:

http://sourceforge.net/projects/softsmithy/files/softsmithy/

メイヴン:

<dependency>  
    <groupid>org.softsmithy.lib</groupid>  
    <artifactid>lib-core</artifactid>  
    <version>0.1</version>  
</dependency> 
于 2011-06-23T10:10:32.233 に答える