日期:2014-05-20  浏览次数:20594 次

泛型<?>问题
之前看李兴华老师的视频.看他喜欢用泛型的时候用这个<?>
刚才自己写了个泛型,也是用<?>为啥老出错呢?
Java code

  ArrayList<?> al = new ArrayList<?>();
  al.add(1)


------解决方案--------------------
怎么写个?号。
ArrayList<?> al = new ArrayList<Integer>()
两边要相同的。你写成ArrayList<Integer> al = new ArrayList<Integer>()就不会出错了
------解决方案--------------------
<?>是泛型的类型通配符,将集合定义成<?>,初始化的时候,你传的什么参数,这个集合就只能添加该类型的参数,可扩展性较好。你可能漏了(<? extends Integer> list)
泛型通配符类型
? extends String 是不确定传入的参数是什么类型的,只知道是String类型的子类(这他妈是谁写出来的东西,String他妈有子类么?)。这个东西只能作为返回参数,不能作为传入参数,因为只知道他是某个类型的子类,但是不确定是什么类型,所以他能够被某个类型以及父类所应用而接受,但是任何类型都不能传入。相对而言还有一个? super String,它的特性跟? extends String正好相反。
你那个东西写错了
要么你就是public void takeList(List<? extends String> list)
要么你就是public void takeList(? extends String list)
------解决方案--------------------
应为
ArrayList<Integer> al = new ArrayList<Integer>()
------解决方案--------------------
ArrayList是必须要有一个确定的参数的
------解决方案--------------------
楼主你上面的代码是不能add任何类型的,除了add(null).

原因如下:

第一:?是个通配符,即代表任何类型,ArrayList<?> 相当于ArrayList<? extends Object>, 而ArrayList<Integer>是 ArrayList<?> 的子类型,所以ArrayList<?> al = new ArrayList<Integer>();是编译没有问题的;

第二:编译器在编译源代码时,是需要知道参数类型的(Java是强类型语言),也就是根据al的声明类型ArrayList<?>来编译,不是根据ArrayList<Integer>来确认元素类型的;上面说了 ?是个通配符,即代表任何类型,注意和某个具体类型的区分,也就是说编译器不知道ArrayList中要存放什么类型,所以使用add()方法添加元素时失败(编译器会根据al中的元素的类型来验证add()能添加什么类型的元素)。null能表示任何类型,其实就是不知道类型。

所以你可以不指明类型ArrayList al = new ArrayList<Integer>()或指明具体类型ArrayList<Integer> al = new ArrayList<Integer>()来改进代码。
------解决方案--------------------
没用过