本以為這會是一篇比較基礎的博客,可一旦深究的時候,才發現很多有意思的東西,也發現了很多令人迷惑的地方。通配符是一個有趣的東西,如果你掌握了,會使你的代碼更為通用(健壯性更強)。首先本文是在建立在java泛型基礎之上的,如果你對泛型並不了解,可以點擊這裡。同時為了對通配符的了解更為透切,定義如下幾個類。
public class Animal { private String name; public Animal(String name) { this.name = name; } public void eat() { System.out.println(getName() + " can eat."); } public String getName(){ return name; } }
public class Cat extends Animal { public Cat(String name) { super(name); } public void jump(){ System.out.println(getName() + " can jump."); } }
public class Bird extends Animal { public Bird(String name) { super(name); } public void fly(){ System.out.println(getName() + " can fly."); } }
public class Magpie extends Bird { public Magpie(String name) { super(name); } public void sing(){ System.out.println(getName() + " can not only eat,but sing"); } }
首先我們看一下無通配符的使用示例,如下:
public class AnimalTrainer { public void act(List<Animal> list) { for (Animal animal : list) { animal.eat(); } } }
測試代碼如下:
public class TestAnimal { public static void main(String[] args) { AnimalTrainer animalTrainer = new AnimalTrainer(); //Test 1 List<Animal> animalList = new ArrayList<>(); animalList.add(new Cat("cat1")); animalList.add(new Bird("bird1")); animalTrainer.act(animalList); //可以通過編譯 //Test 2 List<Cat> catList = new ArrayList<>(); catList.add(new Cat("cat2")); catList.add(new Cat("cat3")); animalTrainer.act(catList); //無法通過編譯 } }
如上,Test 1 的執行應該可以理解的,不過順帶提醒一下的是,因為cat1和bird1都是Animal對象,自然可以添加List<Animal>裡,具體解釋可參考Java泛型基礎 。對於Test 2,無法通過編譯是因為List<Cat>並不是List<Animal>子類,傳入參數有誤,也就無法通過編譯了。現在嘗試去修改AnimalTrainer.act()代碼,讓它變得更為通用的一點,即不僅僅是接受List<Animal>參數,還可以接受List<Bird>等參數。那如何更改呢??
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-10/90928p2.htm