理由はSet<Set<String>>
がSet<HashSet<String>>
と等価ではないということです! Set<HashSet<String>>
のみHashSet<String>
を含んでいてもよいしながらSet<Set<String>>
は、Set<String>
の任意タイプを含んでいてもよいです。
Set<Set<String>> set = new HashSet<HashSet<String>>()
が合法であれば、あなたもエラーなしでこれを行うことができますが:
Set<HashSet<String>> setOfHashSets = new HashSet<HashSet<String>>();
Set<Set<String>> set = setOfHashSets;
set.add(new TreeSet<String>());
HashSet<String> wrong = set.iterator().next(); // ERROR!
しかし、ここでは有界ワイルドカードを使用することは合法です:
Set<? extends Set<String>> set = setOfHashSets;
これが原因で今許可されていますセットに含まれるオブジェクトのタイプは? extends Set<String>
...つまり、「が不明です。クラスは、実装すると、Set<String>
」となります。 Set<String>
の特定のタイプが何であるかを正確には分からないので、それに何も追加することはできません(null
を除く)...間違っている可能性があります。最初の例。
編集:
注意あなたがあなたの質問にを参照してください。「トップレベル」のジェネリックは、1つのまたは複数の型パラメータを取るタイプを意味し、パラメータ化された型と呼ばれていること。 Set<Set<String>> set = new HashSet<Set<String>>()
が合法である理由は、HashSet<T>
がSet<T>
を実装するため、サブタイプがSet<T>
であるためです。ただし、型パラメータT
は一致する必要があります。サブタイプがT
の別のタイプS
がある場合、HashSet<S>
(または唯一のSet<S>
偶数)はサブタイプSet<T>
ではありません!上記の理由を説明しました。
これはまさにここの状況です。
Set<Set<String>> set = new HashSet<Set<String>>();
私たちはここにT
でSet<String>
を交換した場合、我々はSet<T> set = new HashSet<T>()
を取得します。したがって、実際の型引数が一致すること、および割り当ての右側の型が左側の型のサブタイプであることは容易に分かります。
Set<Set<String>> set = new HashSet<HashSet<String>>();
ここでは、S
がT
のサブタイプである場合、それぞれT
とS
とSet<String>
とHashSet<String>
を交換する必要があります。これで、Set<T> set = new HashSet<S>()
となります。上で説明したように、HashSet<S>
はサブタイプSet<T>
ではないため、割り当てが不正です。
この答えは私に多くの意味がありません。 John KugelmanとColinDは本当に問題をはっきりと説明しています。 – erickson
これは、型パラメータを "推論する"こととは関係ありません。 – ColinD
@ColinD:正しい。一定。 – haylem