から このOracleチュートリアル 、
Integer
はNumber
のサブタイプですが、List<Integer>
はList<Number>
のサブタイプではなく、実際、これら2つのタイプは関連していません。
List<Number>
とList<Integer>
の共通の親はList<?>
です。
私の質問は2番目の文についてです。 List<?>
がList<Number>
とList<Integer>
の共通の親であるとどのように言うことができますか?
?
は不明な型を表し、任意の参照型である可能性があります。ここで?
はObject
になると言っても、Object
がInteger
とNumber
の共通の親であるからといってList<Object>
はList<Integer>
とList<Number>
の共通の親になります。
理解する必要のあるコンテキストは、Integer
またはNumber
ではありませんが、List
です。あなたがList
クラスを作成していると仮定して、特定のタイプのクラスのみをサポートするようにクラスをどのように作成しますか。
はい、そのList
クラスはそのタイプとしてObjectを使用せず、代わりにワイルドカード?
を使用します。
として ワイルドカードのドキュメント 言う
では、あらゆる種類のコレクションのスーパータイプは何ですか?
Collection<?>
(「未知のコレクション」と発音)と書かれています
リストについても同じことが言えます。
では、すべての種類のリストのスーパータイプは何ですか?
List<?>
(「不明のリスト」と発音)と書かれています
List<?>
がList<Number>
とList<Integer>
のスーパータイプであることを証明できます。
JLS 4.10.2 (私の強調)から:
ジェネリック型宣言C <F1、...、Fn>(n> 0)が与えられると、パラメーター化された型
C<T1,...,Tn>
の直接スーパータイプ、ここでTi(1 ≤i≤n)はタイプであり、次のすべてです。
.。
C<S1,...,Sn>
、ここでSi
containsTi
(1≤i≤n)(§4.5.1 )
C
をList
とn=1
に置き換えることで、List<?>
がList<Number>
とList<Integer>
の直接のスーパータイプであることがわかりますif?
にはNumber
とInteger
が含まれます。
?
containsNumber
およびInteger
が含まれていることを証明できます。これは、 JLS4.5。 1 :
ワイルドカード
? extends Object
は、無制限のワイルドカード?
と同等です。
そしてさらに:
型引数
T1
はcontain別の型引数T2
と呼ばれ、T2
<=T1
、T2
で示される型のセットが、次のルールの再帰的および推移閉包の下でT1
で示される型のセットのサブセットであることが証明される場合(<:はサブタイプを示します(§4.10 ))::
? extends T
<=? extends S
if T <:S- .。
T
<=? extends T
上記のルールを使用して、Number
<= ?
であることを証明できます。これは、Number
<= ? extends Number
<= ? extends Object
= ?
。
チュートリアルはワイルドカードについてです。だから彼らはあなたがそれらをいつどのように使うべきかを説明したいと思っています。先読みすると、サンプルコードがあります。
List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // OK. List<? extends Integer> is a subtype of List<? extends Number>
この割り当ては、?
がInteger
とNumber
の共通の親である場合にのみ実行できます。ワイルドカードとジェネリックスとの関係では、次のように言うことができると思います。
List<?>
は、List<Number>
とList<Integer>
の共通の親です。
チュートリアルのコンテキストを確認する必要があるためです。
OOP継承またはコンクリート型)の概念をの概念と混合しています)ジェネリック型およびこれらのジェネリック間の関係。
ワイルドカードとサブタイプ に関するチュートリアルの1つの文は、すべてを述べています。
これらのクラス間の関係を作成するには...上限のワイルドカードを使用します
一般的な型の関係?
は、可能なワイルドカード? extends <type>
(上限のワイルドカード)、? super <type>
(下限のワイルドカード)、および実際のtype
(完全一致または "上限と下限のワイルドカード」)。
ワイルドカードは、ジェネリックスとOOP)の両方の概念を取得するために使用されますが、同じではありません。簡単に言えば、List<?>
は、List<Integer>
とList<Number>
の共通の親です。関係は、他のワイルドカードが?
とのサブタイプ関係を作成するように指定されます。これは多かれ少なかれ非公式な説明です。仕様の具体的な部分については、dejvuthの回答を参照してください。
メソッドがJava withgenericsで持つタイプは次のとおりです。
interface Collection<E> {
...
public boolean contains(Object o);
public boolean containsAll(Collection<?> c);
...
}
最初の方法はジェネリックをまったく使用しません! 2番目の方法は、重要な略語を最初に目にした方法です。タイプコレクションの略:
Collection<? extends Object>
オブジェクトの拡張はワイルドカードの最も一般的な使用法の1つであるため、オブジェクトを記述するための短い形式を提供することは理にかなっています。