Java基础之泛型

先直接上段代码:

public class Demo<T extends Animal>{
	private T obj;
    public Demo(T obj) {
        super();
        this.obj = obj;
    }

    public T getOb() {
        return obj;
    }
    public void setOb(T ob) {
        this.obj = obj;
    }

    public void printClassT(){
        System.out.println("T的类型是:"+obj.getClass().getName());
    }
}

先给个结论:集合的泛型主要是防止错误的输入类型,只在编译阶段起作用。
上面是自定义的一个类Demo< T extends Animal >,提供对Animal类的各种操作,如输出Animal子类的类名。

Demo< T >的含义:
在此之前,需要先明白Demo< T >的含义,T表示输入的参数是一个具体的类型,Demo< T >
Demo类中会对T类型数据进行一定的操作,类比ArrayList< String string >,ArrayList中对String数据类型进行List的add、remove等操作。

Demo< T extends Animal >:
Demo< T extends Animal >是Demo< T >的升级版 ,提供对T类型对象的操作,但限定了T类型的上限(范围),即T必须是Animal的子类
Animal类:

public class Animal {
    public String name = "animal";
    
    public void action(){
        System.out.println("I’m animal: animal shout...");
    }
}

定义Cat、Dog分别继承Animal类
Cat:

public class Cat extends Animal{
    @Override
    public void action() {
        System.out.println("I;m Cat, miao miao miao...");
    }
}

Dog:

public class Dog extends Animal{
@Override
public void action() {
    System.out.println("I,m Dog, wang wang wang...");
}

}

下面定义测试类GenericTest进行测试:
根据定义的Demo< T extends Animal>,在Demo的泛型中只要是Animal的子类都不会有问题,因此
Demo< Dog >、Demo< Cat >、Demo< Animal >有问题,但只要往Demo中装入非Animal的类,就会报错。

    Demo<Dog> dogDemo = new Demo<Dog>(new Dog());
    Demo<Cat> catDemo = new Demo<Cat>(new Cat());
    Demo<Animal> animalDemo = new Demo<Animal>(new Animal());
    
    // Demo<Cat> aa = new Demo<Wind>(new Cat());    // 报错

接下来定义2个函数:

/* 1.Demo<T> animal   -->   Demo<Cat> cat */
private static void takeCat(Demo<Cat> catDemo){   
    catDemo.printClassT();   
}

/* 2.Demo<T> animal   -->   Demo<Animal> animal */
private static void takeAnimal(Demo<Animal> animal){ 
    animal.printClassT();   
}

// 测试
Demo<Dog> dogDemo = new Demo<Dog>(new Dog());
Demo<Cat> catDemo = new Demo<Cat>(new Cat());
Demo<Animal> animalDemo = new Demo<Animal>(new Animal());

takeCat(catDemo);    // 可行
takeCat(dogDemo);    //输入数据类型错误,takeCat(Demo<Cat> catDemo)只能输入Demo<Cat>类数据

takeAnimal(animalDemo) // 可行
takeAnimal(dogDemo)    // 输入数据类型错误,takeAnimal(Demo<Animal> animal)只能输入Demo<Animal>类数据

总结:
前提:在编译过程中在编译过程中在编译过程中(重要事情说三遍),Demo< T extends Animal >中,Demo中可以装任意的Animal的子类数据,但确定装入不同的子类的数据类型后,如Demo< Cat >、Demo< Dog >、 Demo< Animal >,这个装不同的数据类型的Demo就是不同的数据类型。即
Demo< Cat >、Demo< Dog >、 Demo< Animal >是不同的数据类型,犹如Student类与Teacher类一样。但仅仅是在编译过程中。

因为泛型仅仅是防止错误的数据类型输入的,泛型就相当于在我家门外安装一个指纹锁一样,只有指纹正确才表示是我家人(数据类型相同),才让进入。仅此一道防线而已,但我家还是我家,没有任何变化。在编译后Demo< Cat >、Demo< Dog >、 Demo< Animal >数据类型依旧相同,都是Demo类。

具体原因可以看我另一篇文章 反射机制Reflect与泛型 https://blog.csdn.net/qq_27567543/article/details/106070219
欢迎指正和交流~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值