List<? extends Number> list1 = new ArrayList<Number>(){
{addAll(Arrays.asList(1,2,3,4,5));}
};
ListIterator listIterator = list1.listIterator();
listIterator.next();
listIterator.set(999);
System.out.println(list1);
该代码有效
[999, 2, 3, 4, 5]
但是,如果我这样写:
List<? extends Number> list1 = new ArrayList<Number>(){
{addAll(Arrays.asList(1,2,3,4,5));}
};
list1.set(0,999);
我知道了
java: method set in interface java.util.List<E> cannot be applied to given types;
required: int,capture#1 of ? extends java.lang.Number
found: int,int
reason: actual argument int cannot be converted to capture#1 of ? extends java.lang.Number by method invocation conversion
请Plese澄清此行为。
附言
这个问题是在观看来自
Collections.reverse
方法public static void reverse(List<?> list) {
int size = list.size();
if (size < REVERSE_THRESHOLD || list instanceof RandomAccess) {
for (int i=0, mid=size>>1, j=size-1; i<mid; i++, j--)
swap(list, i, j);
} else {
ListIterator fwd = list.listIterator();
ListIterator rev = list.listIterator(size);
for (int i=0, mid=list.size()>>1; i<mid; i++) {
Object tmp = fwd.next();
fwd.set(rev.previous());
rev.set(tmp);
}
}
}
最佳答案
如果您的代码示例完整,那是因为您已从ListIterator定义中删除了通用信息。如果要更改它以包含通用信息,它将返回类似的编译错误:
List<? extends Number> list1 = new ArrayList<Number>(){
{addAll(Arrays.asList(1,2,3,4,5));}
};
ListIterator<? extends Number> listIterator = list1.listIterator();
listIterator.next();
listIterator.set(999);
System.out.println(list1);
同样,如果从列表中删除了通用定义,则可以直接添加项目而不会出现问题:
List<? extends Number> list1 = new ArrayList<Number>(){
{addAll(Arrays.asList(1,2,3,4,5));}
};
List list2 = list1;
list2.set(0,999);
这全部归结为一个事实,即泛型实际上只是语法糖,有助于编译,但在运行时会被“擦除”。
http://docs.oracle.com/javase/tutorial/java/generics/erasure.html