Java 通配符解惑

本以为这会是一篇比较基础的博客,可一旦深究的时候,才发现很多有意思的东西,也发现了很多令人迷惑的地方。通配符是一个有趣的东西,如果你掌握了,会使你的代码更为通用(健壮性更强)。首先本文是在建立在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 list) {
        for (Animal animal : list) {
            animal.eat();
        }
    }
}

测试代码如下:

public class TestAnimal {
    public static void main(String[] args) {
        AnimalTrainer animalTrainer = new AnimalTrainer();
        //Test 1
        List animalList = new ArrayList<>();
        animalList.add(new Cat("cat1"));
        animalList.add(new Bird("bird1"));
        
        animalTrainer.act(animalList);  //可以通过编译
        
        //Test 2
        List catList = new ArrayList<>();
        catList.add(new Cat("cat2"));
        catList.add(new Cat("cat3"));
        
        animalTrainer.act(catList);     //无法通过编译
    }
}

如上,Test 1 的执行应该可以理解的,不过顺带提醒一下的是,因为cat1和bird1都是Animal对象,自然可以添加List里,具体解释可参考Java泛型基础 。对于Test 2,无法通过编译是因为List并不是List子类,传入参数有误,也就无法通过编译了。现在尝试去修改AnimalTrainer.act()代码,让它变得更为通用的一点,即不仅仅是接受List参数,还可以接受List等参数。那如何更改呢??

更多详情见请继续阅读下一页的精彩内容http://www.linuxidc.com/Linux/2013-10/90928p2.htm

推荐阅读

Java中泛型之类型通配符(?) http://www.linuxidc.com/Linux/2012-10/72626.htm

Java 泛型类型通配符 http://www.linuxidc.com/