1.什么是泛型:
说白了就是我希望集合可以记得住我存进去的数据是什么类型的,以此做一个筛选,不是同类型的就不允许在一块存放,这样也避免了ClassCastException错误的出现,因为都是同一类型,也就没必要做强制类型转换了。
ps:ClassCastException :就是不能将整型Integer转换成String字符串类型,就是类型不匹配啊
了解泛型可查看博客:(105条消息) 怒干一万字,带你真正理解Java的泛型!_庆哥Java的CSDN技术博客-CSDN博客
2.类型擦除:
会报错: both methods hava some erasure;
原因是java在编译的时候会把泛型,上面的String和Integer给 擦除掉,java的泛型机制是在编译级别实现的,编译器生成的字节码在允许期间不包含泛型的类型 信息。
注意:但并没有真正擦除掉。
3.不变:
ArrayList 是List的子类,apple是fruit的子类,为什么这里的泛型转换出问题了?
原因是泛型没有内建的协变类型 。无法关联起来,也就就是没有关系。
4.协变:
我们可以利用通配符<? extends fruit> 进行泛型的转换,?代表子类的某一个, 可以实现我们的向 上转换
List <? extends fruit> list = new ArrayList<apple>();
转换后的list类型是<? extendsfruit> 因为?是父类的某一个子类,所以导致使用了这个向上转型后,无法使用add进行添加元素,但可以使用get获取元素。
只能选择从list当中get数据而不能add。
但注意这个时候从list中get到的数据不再是Apple ,而是fruit或者fruit的父类。
5.逆变:
List <? super apple> list = new ArrayList<fruit>();
跟协变相反,逆变是向下转型 通过使用通配符<? super T> (超类通配符)
总结一下,便于记忆:
协变:extends/向上转换/不能add/只能get(T及父类)
逆变:super/向下转换/不能get/只能add(T及子类)
get元素的时候需要进行强制转换