ArrayList是一個(gè)使用泛型的類,它的類聲明如下:
public class ArrayList<E> extends AbstractList<E> implement List<E> ...{
public boolean add(E o)...
}
當(dāng)我們定義一個(gè)方法如下:
public void takeAnimal(ArrayList<Animal> animals){
...
}
當(dāng)我定義個(gè)實(shí)例對(duì)象 ArrayList<Animal> animals = new ArrayList<Animal>()
然后使用 takeAnimal(animals)
來調(diào)用我們定義的方法漓帚,編譯并運(yùn)行程序母债,程序能夠正常運(yùn)行;
??重新實(shí)驗(yàn)尝抖,當(dāng)我創(chuàng)建一個(gè) Animal 的子類 Cat 的實(shí)例對(duì)象毡们,例如 ArrayList<Cat> cats = new ArrayList<Cat>()
,然后我們?cè)偈褂?takeAnimal(cats)
來調(diào)用之前定義的方法昧辽,編譯衙熔,這個(gè)時(shí)候程序會(huì)報(bào)錯(cuò),錯(cuò)誤大致如下:
java.util.ArrayList<Animal> cannot be applied to java.utils.arrayList<Dog>
** Cat 明明為 Animal 的子類搅荞,為什么不能作為參數(shù)傳遞呢红氯?**
??理由其實(shí)簡(jiǎn)單,根據(jù)Java面向?qū)ο蟮奶匦怨就础T囅胂肓「剩绻诜椒▋?nèi)我添加Animal其他子類的對(duì)象怎么辦,例如:我們添加 Animal 的另一子類 Dog 茉贡,代碼如下:
public void takeAnimal(ArrayList<Animal> animals){
animals.add(new Dog);
}
此時(shí) animals 引用實(shí)際上持有的是ArrayList<Cat> 對(duì)象塞栅,而 Cat 與 Dog 雖然擁有同一父類,但它們之間并沒有 is-a 或者 has-a 關(guān)系腔丧,因此 Dog 不能添加到 animal 中放椰。而在這個(gè)方法中 animals.add(new Dog);
確實(shí)在語法上沒有錯(cuò)誤,Java 為了避免這個(gè)問題愉粤,在編譯時(shí)就會(huì)提示之前的錯(cuò)誤砾医。
那么我們是不是要為每一個(gè)類的 ArrayList 參數(shù)定義一個(gè)方法呢??
??答案是不用R吕濉H缪痢!Java 為我們提供了一個(gè)方案:使用泛型與萬用字符。例如我們重寫方法
public void takeAnimals(ArrayList<? extends Animal> animals){
...
}
或者
public <T extends Animal> void takeAnimals(ArrayList<T> animals){
...
}
使用上述方法后我們使用 takeAnimal(cats)
來調(diào)用方法就不會(huì)報(bào)錯(cuò)了错邦,但是有一個(gè)問題需要注意涎显,在該方法體中不會(huì)允許你向 animals 添加任何元素。