本帖最后由 孙百鑫 于 2013-6-22 01:01 编辑
看到很多人对泛型上下限有点纠结,我总结了下用法,共同学习进步。 那么泛型限定什么时候用上限,什么时候用下限呢?其实限定的原理理解了, 这个在使用时是很容易区分的,即使你说不出具体什么时候用哪个,但是真正遇到时稍加判断就知道了。
为了方面学习与复习,还是总结归纳分析一下。 首先第一篇中我们定义的那个方法,具体实现可以如下: 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()}
我们定义的方法是既能接收a1(person)又能接受a2(student),我们为什么要这样做,原因很简单, 就是我们想用父类的方法,子类也有,顺便就可以接受了拿来用。要用person里面的东西,所以我们 要接受person或person子类,或者如果我们往一个集合中存入另一个包含某类对象的集合,比如我们 往一个TreeSet里存入Collection<person>,此时当然也可以接收person子类的collection集合, 用的也是person的方法,它的子类照样可以被做为person用,这其实也是变相的多态体现,用上限, 这很容易理解,毕老师管它叫做装入集合时用上限。
那么什么时候用下限呢?这种情况就是我们并不是要使用集合内的对象本身,而是拿来这些对象, 对这些对象进行一些操作,比如迭代,比较。例如我们要定义一个比较器comparator来对TreeSet内的Student对象进行比较, TreeSet( Comparator<;Person> comparator),因为 student是person子类,能接受person的比较器自然也能接受person的子类, 这里就可以写成TreeSet(Comparator<? super E> comparator) , 即泛型下限,这里接收的比较器即可以是要比较对象的,也可以是要比较对象的父类的,这其实也是多态体现。
这里总结下:*要往集合中存储集合时,这个接收的集合参数用泛型上限。 *要把集合中元素拿出来放在某种“器”内时,这个器参数用泛型下限。
即假设 A extends B extends C
我们想要要存B时,也能存顺便接受A(因为我们既然想存B,那么肯定是以后是想用B,里面有A也无妨), 后来要取B时,能用B的接收器取,也能用C的接收器取,就是上限下限应用 (注意我们真正的重点目标并不是? extends B或? super B中的?,而是?后面的那个“限”)
|