3

次の 3 つの署名の違いは何ですか?

static <T> void foo(List<T>,           Comparator<? super T>);
static <T> void bar(List<? extends T>, Comparator<T>        );
static <T> void baz(List<? extends T>, Comparator<? super T>);

私はジェネリックで何extendsを意味するかを知っています。私の質問は、とsuperの間に違いがあるかどうかです。パラメータの 1 つを不変にし、他の 1 つを適切な方向に変更する必要がありますか、それとも両方を変更する必要がありますか? 違いはありますか?foobarbaz

4

3 に答える 3

5

PECS - 生産者は拡張し、消費者はスーパー。

この「ルール」を説明するには:

  • extendsジェネリック化されたオブジェクトが型の要素を生成することを意味します。コレクションの場合、コレクションから要素を取得することはできますが、コレクションに入れることはできません。
  • superオブジェクトが選択されたタイプのオブジェクトを消費することを意味します。したがって、コレクションに追加することはできますが、コレクションから読み取ることはできません。
  • extends と super がないということは、指定された正確なタイプに対して両方を実行できることを意味します。

に関してはComparator、大差ないと思います。通常は<? super T>、コンパレーターがオブジェクトを消費するためですが、3 つのケースすべてで安全に呼び出すことができますCollections.sort(list, comparator);(その署名は です<? super T>) 。

于 2012-03-17T22:42:24.787 に答える
2

唯一の違いは、 が 、 、またはその中間Tの型パラメーターを表すかどうかです。ListComparator

呼び出し元に関する限り、3 つのメソッド シグネチャは同等です。つまり、そのうちの 1 つを使用できる場合は常に、他のメソッド シグネチャも使用できます。

メソッドの実装fooはおそらく最も便利です。追加のキャプチャ変換を必要とせずにリストを変更できるため、ヘルパー メソッドへの委譲が必要になります。

于 2012-03-18T00:15:40.773 に答える
1

これは、 が T から派生した任意の型のジェネリックで? extends Tある可能性があることを意味すると思いますが、その派生クラスのいずれかではなく、の であることができます。ListList<T>ListT

于 2012-03-17T22:43:00.903 に答える