先直接上段代码:
public class Demo{
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 dogDemo = new Demo(new Dog());
Demo catDemo = new Demo(new Cat());
Demo animalDemo = new Demo(new Animal());
// Demo aa = new Demo(new Cat()); // 报错
接下来定义2个函数:
/* 1.Demo animal --> Demo cat */
private static void takeCat(Demo catDemo){
catDemo.printClassT();
}
/* 2.Demo animal --> Demo animal */
private static void takeAnimal(Demo animal){
animal.printClassT();
}
// 测试
Demo dogDemo = new Demo(new Dog());
Demo catDemo = new Demo(new Cat());
Demo animalDemo = new Demo(new Animal());
takeCat(catDemo); // 可行
takeCat(dogDemo); //输入数据类型错误,takeCat(Demo catDemo)只能输入Demo类数据
takeAnimal(animalDemo) // 可行
takeAnimal(dogDemo) // 输入数据类型错误,takeAnimal(Demo animal)只能输入Demo类数据
总结:
前提:在编译过程中,在编译过程中,在编译过程中(重要事情说三遍),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
欢迎指正和交流~