[Java]集合与泛型

普通数组的工作方式

如下面的代码,函数takeAnimals的参数类型是Animal[[],在调用的时候,可以把Animal[]或者Dog[]传递进去( Dog是Animal的派生类)

import java.util.*;

public class TestGenerics1 {
    public static void main( String[] args ) {
        new TestGenerics1().go();
    }

    public void go() {
        Animal[] animals = { new Dog(), new Cat(), new Dog() };
        Dog[] dogs = { new Dog(), new Dog(), new Dog() };
        takeAnimals( animals );
        takeAnimals( dogs );
    }

    public void takeAnimals( Animal[] animals ) {
        for( Animal a : animals ) {
            a.eat();
        }
    }
}

泛型的工作方式

我们把上例的Array替换为ArrayList

    public void go() {
        ArrayList<Animal> animals = new ArrayList<Animal>();
        animals.add( new Dog() );
        animals.add( new Cat() );
        animals.add( new Dog() );

        takeAnimals( animals );
    }

    public void takeAnimals( ArrayList<Animal> animals ) {
        for( Animal a : animals ) {
            a.eat();
        }
    }

如上,takeAnimals传入ArrayList<Animal>是可以正常编译运行,没有问题的;但是如果仿照Array的例子,我们可以将ArrayList<Dog>传入takeAnimals吗?

ArrayList<Dog> dogs = new ArrayList<Dog>();
dogs.add( new Dog() );
dogs.add( new Dog() );
dogs.add( new Dog() );

takeAnimals( dogs );

上面这段code会compile error。

如果可以会怎样?

public void takeAnimals( ArrayList<Animal> animals ) {
    animals.add( new Cat() );
}

如果ArrayList<Dog>可以传递给takeAnimals,那会出现Cat混入Dog集合的情形。

原因

数组的类型是在运行期间检查的,但集合的类型检查只会发生在编译期间

解决办法

public void takeAnimals( ArrayList<? extends Animal> animals ) {
    for( Animal a: animals ) {
        a.eat();
    }
}

在使用带有<?>的声明时,编译器不会让你往集合中加入任何东西,只能读取。

另外一种相同功能的语法

public <T extends Animal> void takeAnimals( ArrayList<T> animals );

为什么要用这种形式?

如果要多次使用,会更有效率

public <T extends Animal> void takeThing< ArrayList<T> one, ArrayList<T> two )

// 而不必像下面这样
public void takeThing< ArrayList<? extends Animal> one, ArrayList<? extends Animal> two )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值