それはあなたが何をする必要があるかによって異なります。次のようなことをしたい場合は、境界型パラメーターを使用する必要があります。
public <T extends Shape> void addIfPretty(List<T> shapes, T shape) {
if (shape.isPretty()) {
shapes.add(shape);
}
}
ここに aList<T> shapes
と aT shape
があるので、安全に できshapes.add(shape)
ます。宣言されている場合、安全にList<? extends Shape>
アクセスすることはできませんadd
( と がある可能性があるためList<Square>
) Circle
。
したがって、境界型パラメーターに名前を付けることで、ジェネリック メソッドの他の場所で使用するオプションが得られます。もちろん、この情報は常に必要なわけではありません。そのため、タイプ (たとえば、あなたの ) についてそれほど知る必要がない場合は、drawAll
ワイルドカードだけで十分です。
境界型パラメーターを再度参照していない場合でも、複数の境界がある場合は、境界型パラメーターが必要です。以下は、 Angelika Langer の Java Generics FAQからの引用です。
ワイルドカード バウンドと型パラメーター バウンドの違いは何ですか?
ワイルドカードは 1 つの境界のみを持つことができますが、型パラメーターは複数の境界を持つことができます。ワイルドカードには上限または下限を指定できますが、型パラメーターには下限などはありません。
ワイルドカードの境界と型パラメーターの境界は、どちらも境界と呼ばれ、構文の一部が似ているため、混同されることがよくあります。[…]
構文:
type parameter bound T extends Class & Interface1 & … & InterfaceN
wildcard bound
upper bound ? extends SuperType
lower bound ? super SubType
ワイルドカードに指定できる境界は、下限または上限のいずれか 1 つだけです。ワイルドカード境界のリストは許可されていません。
対照的に、型パラメーターは複数の境界を持つことができますが、型パラメーターの下限などはありません。
有効な Java 2nd Edition、項目 28からの引用: API の柔軟性を高めるには、境界付きワイルドカードを使用します。
最大限の柔軟性を得るには、プロデューサーまたはコンシューマーを表す入力パラメーターでワイルドカード タイプを使用します。[…] PECS は生産者extends
、消費者の略super
[…]
戻り値の型としてワイルドカード型を使用しないでください。ユーザーに追加の柔軟性を提供するのではなく、クライアント コードでワイルドカード型を使用することを強制します。適切に使用されたワイルドカード型は、クラスのユーザーにはほとんど見えません。これらは、メソッドが受け入れるべきパラメーターを受け入れ、拒否すべきパラメーターを拒否するようにします。クラスのユーザーがワイルドカード型について考える必要がある場合は、クラスの API に問題がある可能性があります。
PECS の原則を適用して、addIfPretty
例に戻り、次のように記述してより柔軟にすることができます。
public <T extends Shape> void addIfPretty(List<? super T> list, T shape) { … }
これでaddIfPretty
、たとえば、 aCircle
から a にできList<Object>
ます。これは明らかにタイプセーフですが、元の宣言はそれを許容するほど柔軟ではありませんでした。
関連する質問
概要
- 境界型パラメーター/ワイルドカードを使用してください。API の柔軟性が向上します。
- 型に複数のパラメーターが必要な場合は、バインドされた型パラメーターを使用するしかありません
- 型に下限が必要な場合は、制限付きワイルドカードを使用するしかありません
- 「生産者」には上限があり、「消費者」には下限があります
- 戻り値の型にワイルドカードを使用しないでください