最近在学java,学习到泛型的时候总是对List, List<Object>, List<?>之间的区别比较迷惑,自己找了点资料整理了下思路,说的不对的地方,欢迎拍砖~
这三个List的写法可以从赋值和使用两个方面来分析:
List:
List表明没有制定泛型参数,因此在赋值的时候,任意类型List<T>都可以向List赋值;使用List的时候,只要是Object类型的对象,都可以从List中add或者是get,但容易出现以下程序的尴尬,
List
list = new ArrayList<Integer>();// T为Integer
list.add(new
String("aaa"));
//Integer
i = listInt.get(0);// 运行时抛出java.lang.ClassCastException
因此写程序的时候尽量不要写这样不负责任的代码。
List<?>或者是List<? extends Base>:
其中,
"?" 为通配符,表示未知类型
List<?>表明泛型参数未知,因此任意类型List<T>都可以向List<?>赋值,比如:
List<?>
list = new ArrayList<Integer>();// T为Integer
List<?
extends Base>表明泛型参数是Base类或者是Base的子类,也就是当List<T>中T的类型为Base类或者是Base的子类的时 候,List<T>才能赋值给List<? extends Base>:
List<?
extends Number> list = new ArrayList<Integer>(); // ok,T为Integer,Base为Number
//List<?
extends Integer> list = new ArrayList<Number>(); // 不ok,T为Number,Base为Integer
未指定泛型参数的对象也可赋值给List<?
extends Number>:
List<?
extends Number> list = new ArrayList();
//List<?
extends Number> list = new ArrayList<Object>(); // 不ok
List<?>和List<?
extends Base>在使用的时候,只能使用get方法, List<?>.get返回元素类型为Object,List<? extends Base>返回元素类型为Base; 但List<?>和List<? extends Base>都不能使用add方法,因为 ? 表示类型不确定, 因此防止add的元素和原有List的泛型参数不一致, add操作时被编译器拒绝的:
List<?
extends Number> list = new ArrayList<Integer>();
Number
n = list.get(0); //ok
//list.add(5);
// 不ok, add方法不可用,编译器不能推导出 "5" 是否是正确的类型
List<Object>:
List<Object>和普通的泛型用法在赋值和使用上没有区别,只是泛型参数是基类Object.
但要注意赋值的时候,java是不允许协变的:
这三个List的写法可以从赋值和使用两个方面来分析:
List:
List<?>或者是List<? extends Base>:
List<Object>:
http://blog.sina.com.cn/s/blog_5cec1e1d0100k08s.html