在下面的例子中,如果列表中有多种类型,它会编译通过,但是如果只有一个元素,则会选择不再可分配的不同类型。
// 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>>
为什么有两个元素可以编译,但只有一个元素不能编译?
顺便说一下:如果你尝试的话,很难找到一个简单的例子。
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的示例。在这四个示例中,其中一个无法编译,其余的产生了相同类型的相同列表。
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));
Class<WeakReference>
不是Class<? extends WeakReference>
,因此自然而然地不能进行赋值。不过,这个例子确实指出了泛型类型系统的弱点。 - Marko Topolnik