ArrayList<? extends Animal>这种一般只应用于作为参数接受一个存放泛型对象的List,获取其中所存的元素,然后调用共有的Animal中的方法。
ArrayList<? extends Animal> list=new ArrayList<Cat>();这种根本无法象普通类型一样向上转型,即你这个list不等于一个ArrayList<Animal>,也不等于一个ArrayList<Cat>。
list指向一个泛型为Cat的list,那么定然不能接受Dog对象,事实上,你用一个 ArrayList<? extends Animal>类型的引用指向它之后,他根本不能add任何对象,因为这个引用可能接受任何Animal的子类,也就是说它的实际类型可能是任意一个? extends Animal,这种模糊类型的引用根本无法添加具体类型的对象,因为允许添加就可能出错。
这点跟多态不同,一个Animal引用指向一个任意的Animal子类,就意味着可以调用这个引用执行所有Animal能做的事情。而他引用的任意一个Animal子类都具备Animal类的功能,所以不会出错。而一个ArrayList<Animal>引用理论上应该可以添加任意Animal对象,但是你让ArrayList<Animal> list= ArrayList<Cat>;的话,list引用应该具备add一个Dog的能力,但是右边却只能add一个Cat而不能add一个Dog,左右两边功能不符,所以直接报错。 ArrayList<? extends Animal>跟ArrayList<Animal>还不一样, ArrayList<? extends Animal>本身可存储的对象都不确定,因为他允许指向任意一个泛型为animal子类的list,但指向后无法调用add方法,因为指向<Cat>就无法添加Dog,指向Dog就无法添加Cat。这种引用接收后,只能遍历容器中的元素,并调用容器中的共有方法,比如ArrayList<? extends Animal>引用中的元素都is a Animal,因此都可以调用Animal中的方法,但是却不能添加任意的元素。 |