List<Object> list = new ArrayList<Object>();
list.add(new Integer(5));
Object a = list.get(0);
<? extends T> 和<T>有什么区别呢?
<? extends Object> ?表示是Object 的子类或者 Object都可以;
这里如果是前者那么会编译报错;
原因:前者的? 直接是在T的子类里面的具体的某一个类,但是编译器无法确定到底是哪一个子类,也就无法add具体是那种类型的子类,这样写就是为了不能add操作。
也就是说这个list不是一个给予、生产的对象,只能用于获取。
<? super T> 和直接<T>有什么区别呢?
List<? super Integer> list = new ArrayList<Integer>();
list.add(new Integer(5));
Integer a = (Integer) list.get(0);
<? super Integer> ?表示是Integer 的父类或者 Integer都可以;
那么属于Integer 的子类 或者Integer的 毫无疑问,list是可以添加的,但是在获取的时候只能通过Object来转换.
java.util.Collections 里面源码:List<? super T>消费者(可以添加T的子类和T)从List<? extends T>生产者(只能获取T或者T的子类[子类需要转型cast])中获取数据
copy(List<? super T> dest, List<? extends T> src)
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
int srcSize = src.size();
if (srcSize > dest.size())
throw new IndexOutOfBoundsException("Source does not fit in dest");
if (srcSize < COPY_THRESHOLD ||
(src instanceof RandomAccess && dest instanceof RandomAccess)) {
for (int i=0; i<srcSize; i++)
dest.set(i, src.get(i));
} else {
ListIterator<? super T> di=dest.listIterator();
ListIterator<? extends T> si=src.listIterator();
for (int i=0; i<srcSize; i++) {
di.next();
di.set(si.next());
}
}
}
当然可以通过反射直接绕过编译器泛型的检查,这样生产者也可以消费了
List<? extends Integer> list = new ArrayList<Integer>();
Method method = list.getClass().getMethod("add",Integer.class);
method.invoke(list,5);
<span style="white-space:pre"> </span>// list.add(5);
Integer a = list.get(0);
System.out.println(a);
注释的是不用反射直接添加,要报错