web-dev-qa-db-ja.com

List <?>はList <Integer>とList <Number>の共通の親ですか?

から このOracleチュートリアル

IntegerNumberのサブタイプですが、List<Integer>List<Number>のサブタイプではなく、実際、これら2つのタイプは関連していません。

List<Number>List<Integer>の共通の親はList<?>です。

私の質問は2番目の文についてです。 List<?>List<Number>List<Integer>の共通の親であるとどのように言うことができますか?

?は不明な型を表し、任意の参照型である可能性があります。ここで?Objectになると言っても、ObjectIntegerNumberの共通の親であるからといってList<Object>List<Integer>List<Number>の共通の親になります。

41
Solace

理解する必要のあるコンテキストは、IntegerまたはNumberではありませんが、Listです。あなたがListクラスを作成していると仮定して、特定のタイプのクラスのみをサポートするようにクラスをどのように作成しますか。

はい、そのListクラスはそのタイプとしてObjectを使用せず、代わりにワイルドカード?を使用します。

として ワイルドカードのドキュメント 言う

では、あらゆる種類のコレクションのスーパータイプは何ですか? Collection<?>(「未知のコレクション」と発音)と書かれています

リストについても同じことが言えます。

では、すべての種類のリストのスーパータイプは何ですか? List<?>(「不明のリスト」と発音)と書かれています

29
Basit Anwer

List<?>List<Number>List<Integer>のスーパータイプであることを証明できます。

JLS 4.10.2 (私の強調)から:

ジェネリック型宣言C <F1、...、Fn>(n> 0)が与えられると、パラメーター化された型C<T1,...,Tn>直接スーパータイプ、ここでTi(1 ≤i≤n)はタイプであり、次のすべてです。

  • .。

  • C<S1,...,Sn>、ここでSicontainsTi(1≤i≤n)(§4.5.1 )

CListn=1に置き換えることで、List<?>List<Number>List<Integer>の直接のスーパータイプであることがわかりますif?にはNumberIntegerが含まれます。

?containsNumberおよびIntegerが含まれていることを証明できます。これは、 JLS4.5。 1

ワイルドカード? extends Objectは、無制限のワイルドカード?と同等です。

そしてさらに:

型引数T1contain別の型引数T2と呼ばれ、T2 <= T1T2で示される型のセットが、次のルールの再帰的および推移閉包の下でT1で示される型のセットのサブセットであることが証明される場合(<:はサブタイプを示します(§4.10 ))::

  • ? extends T <= ? extends S if T <:S
  • .。
  • T <= ? extends T

上記のルールを使用して、Number <= ?であることを証明できます。これは、Number <= ? extends Number <= ? extends Object = ?

12
dejvuth

チュートリアルはワイルドカードについてです。だから彼らはあなたがそれらをいつどのように使うべきかを説明したいと思っています。先読みすると、サンプルコードがあります。

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number>  numList = intList;  // OK. List<? extends Integer> is a subtype of List<? extends Number>

この割り当ては、?IntegerNumberの共通の親である場合にのみ実行できます。ワイルドカードとジェネリックスとの関係では、次のように言うことができると思います。

List<?>は、List<Number>List<Integer>の共通の親です。

チュートリアルのコンテキストを確認する必要があるためです。

5
Kevin Wallis

OOP継承またはコンクリート型)の概念をの概念と混合しています)ジェネリック型およびこれらのジェネリック間の関係

ワイルドカードとサブタイプ に関するチュートリアルの1つの文は、すべてを述べています。

これらのクラス間の関係を作成するには...上限のワイルドカードを使用します

一般的な型の関係?は、可能なワイルドカード? extends <type>(上限のワイルドカード)、? super <type>(下限のワイルドカード)、および実際のtype(完全一致または "上限と下限のワイルドカード」)。

ワイルドカードは、ジェネリックスとOOP)の両方の概念を取得するために使用されますが、同じではありません。簡単に言えば、List<?>は、List<Integer>List<Number>の共通の親です。関係は、他のワイルドカードが?とのサブタイプ関係を作成するように指定されます。これは多かれ少なかれ非公式な説明です。仕様の具体的な部分については、dejvuthの回答を参照してください。

3
makadev

メソッドがJava withgenericsで持つタイプは次のとおりです。

interface Collection<E> {
...
public boolean contains(Object o);
public boolean containsAll(Collection<?> c);
...
}

最初の方法はジェネリックをまったく使用しません! 2番目の方法は、重要な略語を最初に目にした方法です。タイプコレクションの略:

Collection<? extends Object>

オブジェクトの拡張はワイルドカードの最も一般的な使用法の1つであるため、オブジェクトを記述するための短い形式を提供することは理にかなっています。

3