19

私はジェネリックをかなり長い間使用していますが、のような構造を使用したことはありませんList<? super T>

どういう意味ですか?それの使い方?消去後はどのように見えますか?

私も疑問に思います:それはジェネリックプログラミング(テンプレートプログラミング?)の標準的なものですか、それとも単なるJavaの「発明」ですか?たとえば、c#は同様の構造を許可しますか?

4

4 に答える 4

11

この構成は、コレクションから別のコレクションにアイテムを消費する場合に使用されます。たとえば、ジェネリックがあり、コレクションをパラメーターとして受け取り、スタックからすべてのアイテムをその中にポップStackするメソッドを追加したいとします。popAll常識的に、このコードは合法である必要があります。

Stack<Number> numberStack = new Stack<Number>();
Collection<Object> objects = ... ;
numberStack.popAll(objects);

ただし、次のように定義した場合にのみコンパイルされますpopAll

// Wildcard type for parameter that serves as an E consumer
public void popAll(Collection<? super E> dst) {
    while (!isEmpty())
    dst.add(pop());
}

コインの反対側は、次のpushAllように定義する必要があります。

// Wildcard type for parameter that serves as an E producer
public void pushAll(Iterable<? extends E> src) {
    for (E e : src)
    push(e);
}

更新: Josh Blochは、このニーモニックを伝播して、使用するワイルドカードタイプを思い出せるようにします。

PECSは、 producer-extends、consumer-superの略です。

詳細については、Effective Java 2nd Ed。、Item28を参照してください。

于 2010-02-22T11:16:03.180 に答える
4

これは「制限付きワイルドカード」と呼ばれます。それは公式チュートリアルで非常によく説明されています。

したがって、チュートリアルで述べたように、リストには1つのサブタイプのオブジェクトが含まれていることがわかります。T

たとえば、 sのみ、またはsList<? extends Number>のみを保持できますが、両方を保持することはできません。IntegerLong

于 2010-02-22T11:18:57.310 に答える
4

これらのことは、型理論では分散として知られて<? extends T>おり、共変表記であり<? super T>、逆変表記です。最も簡単な説明は、共変表記で?拡張される任意のタイプに置き換えることができ、逆変表記で拡張する任意のタイプに置き換えることができるということです。T?T

coとcontra-varianceを使用することは、特に分散が位置に応じて「切り替わる」ため、最初に思われるよりもはるかに困難です。

簡単な例は関数クラスです。を取り、Aを返す関数があるとしますBAそれの正しい表記法は、それが逆変であり、Bos共変であると言うことです。これがどのように当てはまるかをよりよく理解するために、gこの架空の関数クラスを受け取るメソッド(それを呼び出しましょう)を考えてみましょう。ここで、fはanを受け取り、Arc2Daを返すことになっていShapeます。

内部ではg、これfはの受け渡しと呼ばれArc2D、戻り値はArea(を期待するShape)を初期化するために使用されます。

ここで、fパスしたものがanyを受け取り、Shapeを返すとしますRectangle2D。anArc2DもaShapeであるため、にgを渡すときにエラーが発生することはありません。また、aもであるため、のコンストラクタに渡すことができます。Arc2DfRectangle2DShapeArea

その例で分散のいずれかを反転したり、予想されるタイプと実際のタイプを入れ替えたりしようとすると、失敗することがわかります。私は今このコードを書き留める時間がありません、そして私のJavaはとにかくかなり錆びています、しかし私は後で何ができるかを見るでしょう-誰も最初にそれをするのに十分親切でないなら。

于 2010-02-22T11:42:06.340 に答える
0

Java Generics FAQには、Javaジェネリックスに関する適切な説明があります。質問を確認してください。制限付きワイルドカードとは何ですか?これは、構成「?superT」の使用法を詳細に説明しています。

于 2010-02-22T12:22:51.490 に答える