(黑马程序员)泛型的限定原理和使用(二)

来源:互联网 发布:bt软件种子文件 编辑:程序博客网 时间:2024/05/18 17:43

看到很多人对泛型上下限有点纠结,我总结了下用法,共同学习进步。

那么泛型限定什么时候用上限,什么时候用下限呢?其实限定的原理理解了,这个在使用时是很容易区分的,即使你说不出具体什么时候用哪个,但是真正遇到时稍加判断就知道了。

为了方面学习与复习,还是总结归纳分析一下。

首先看第一篇中我们定义的那个方法,具体实现可以如下:

public static void printCollection(Collection<? extends Person> c) {

Iterator<? extends Person> it = c.iterator();

while(it.hasNext()){

Person p = it.next();

System.out.println(p.getName()}

上篇中提到我们定义的方法是既能接收a1person又能接受a2student),我们为什么要这样的,原因很简单,就是我们想用父类的方法,子类也有,顺便就可以接受了拿来用。

要用person里面的东西,所以我们要接受personperson子类,或者如果我们往一个集合中存入另一个包含某类对象的集合,比如我们往一个TreeSet里存入Collection<person>,此时当然也可以接收person子类的collection集合,即TreeSet(Collection<? extends E> c),因为我们存的目标是person,取出时当然用接受person的东西来取,用的也都是person的方法,它的子类照样可以被做为person,这其实也是变相的多态体现,用上限,这很容易理解,毕老师管它叫做装入集合时用上限。

那么什么时候用下限呢?这种情况就是我们并不是要使用集合内的对象本身,而是拿来这些对象,对这些对象进行一些操作,比如,比较。例如我们要定义一个比较器comparator来对TreeSet内的Student对象进行比较,此时就往TreeSet内传比较器,即TreeSet(Comparator<Student>  comparator)

这里我们也可以用

TreeSet(Comparator<Person>  comparator)

因为studentperson子类,能接受person的比较器自然也能接受person的子类,这里就可以写成

TreeSet(Comparator<? super E> comparator) 

即泛型下限,这里接收的比较器即可以是要比较对象的,也可以是要比较对象的父类的,这其实也是多态体现。

这里总结下:*要往集合中存储集合时,集合不仅要操作存储对象,还要拿出来用,也就是要拿出来集合内的对象来使用其特定方法时,这个集合参数用泛型上限。----存对象的集合参数用上取

            *要把集合中元素取出来时,就是对整体对象的操作,整体操作一下就完事了,操作对象的这个东西的参数用泛型下限。-------取对象的参数集合用下限

即假设A    extends   B  extends  C

    我们想要要存B时,也能存顺便接受A(因为我们既然想存B,那么肯定是以后是想用B,里面有A也无妨),后来要取B时,能用B的接收器取,也能用C的接收器取。