本以為這會是一篇比較基礎的博客,可一旦深究的時候,才發現很多有意思的東西,也發現了很多令人迷惑的地方。通配符是一個有趣的東西,如果你掌握了,會使你的代碼更為通用(健壯性更強)。首先本文是在建立在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