Arrays.asList() と互換性のない型 質問する

Arrays.asList() と互換性のない型 質問する

次の例では、リストに複数の型がある場合は正常にコンパイルされますが、要素が 1 つしかない場合は、割り当てられなくなった別の型が選択されます。

// compiles fine
List<Class<? extends Reference>> list = Arrays.asList(SoftReference.class, WeakReference.class);
// but take an element away and it no longer compiles.
List<Class<? extends Reference>> list2 = Arrays.asList(WeakReference.class);
// without giving the specific type desired.
List<Class<? extends Reference>> list3 = Arrays.<Class<? extends Reference>>asList(WeakReference.class);

これには論理的な説明があるはずだが、私には分からない。

    Error:Error:line (30)error: incompatible types
required: List<Class<? extends Reference>>
found:    List<Class<WeakReference>>

2 つの要素はコンパイルされるのに、1 つの要素はコンパイルされないのはなぜですか?

ところで、簡単な例を見つけるのは難しいです。

List<Class<? extends List>> list = Arrays.asList(ArrayList.class, LinkedList.class);

    Error:Error:line (28)error: incompatible types
required: List<Class<? extends List>>
found:    List<Class<? extends INT#1>>
where INT#1 is an intersection type:
INT#1 extends AbstractList,Cloneable,Serializable

これもコンパイルされません(解析すらされません)

List<Class<? extends AbstractList & Cloneable & Serializable>> list = Arrays.asList(ArrayList.class, LinkedList.class);

Error:Error:line (30)error: > expected
Error:Error:line (30)error: ';' expected

しかし、これは問題なくコンパイルされます

static abstract class MyList<T> implements List<T> { }
List<Class<? extends List>> list = 
        Arrays.asList(ArrayList.class, LinkedList.class, MyList.class);
List<Class<? extends List>> list = 
        Arrays.<Class<? extends List>>asList(ArrayList.class, LinkedList.class);

編集: Marko の例に基づきます。これら 4 つの例では、1 つはコンパイルされず、残りは同じタイプの同じリストを生成します。

List<Class<? extends Reference>> list = new ArrayList<>();
list.add(SoftReference.class);
list.add(WeakReference.class);
list.add(PhantomReference.class);

List<Class<? extends Reference>> list = new ArrayList<>(
     Arrays.asList(SoftReference.class));
list.add(WeakReference.class);
list.add(PhantomReference.class);

List<Class<? extends Reference>> list = new ArrayList<>(
     Arrays.asList(SoftReference.class, WeakReference.class));
list.add(PhantomReference.class);

List<Class<? extends Reference>> list = new ArrayList<>(
     Arrays.asList(SoftReference.class, WeakReference.class, PhantomReference.class));

ベストアンサー1

興味深い問題です。起こっていることは次のことだと私は思います。あなたが示したように 2 つの要素がある場合、 からの戻り値の型はasListすべての引数の中で最も具体的な型であり、最初の例では ですList<Reference>。これは と代入互換ですList<? extends Reference>。引数が 1 つの場合、戻り値の型は引数の具体的な型であり、ジェネリックは共変ではないため代入互換ではありません。

おすすめ記事