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

10-08 13:14