<T>、<T>、および<?>は完全に異なります。
class X<T>という名前の型パラメーター (プレースホルダー) を持つジェネリック クラスを宣言しますT。そのクラス内でTは、有効な型です。
X<T> something変数またはフィールドの宣言です。ジェネリック型の変数を宣言し、ジェネリック パラメータの値を指定します。
X<?> something変数またはフィールドの宣言でもあります。ジェネリック型の変数を宣言していますが、ジェネリック パラメータの値を指定していません。
ジェネリック クラスを作成する場合、必要に応じてジェネリック パラメーターに制約を追加し、ユーザーがそのクラスのインスタンス (変数) を宣言するときに許可される型を指定できます。
したがって、class X<T extends SomeClass>柔軟性の低い型パラメーターを持つジェネリック クラスを作成します。
ジェネリック クラス (例: private Collection<String> myStrings) を使用する場合、明らかに、ジェネリック パラメータの値に制約を指定することはできません (既に実際の値を指定しているため)。
したがって、private Collection<String extends Comparable> myStrings意味がありません。
ワイルドカード (またはバインドされていない) パラメーター (例: )を含むジェネリック クラスを使用する場合private Collection<?> myThingies、任意で、パラメーターが何であれ、制約を指定できます。これにより、ジェネリック パラメーターの (不明な) 値について推測することができます。
したがって、private Collection<? extends Runnable> myRunners は型が を実装することを保証する未知の型のコレクションですRunnable。.run()したがって、コレクション内のものを呼び出すことができます。
ただし、コレクションが実際に保持する必要がある型がわからないため、コレクションに何も入れることはできません。