泛型是将类型参数化,允许定义在类、接口、方法时使用类型参数,当使用的时候指定具体类型。
泛型主要应用在集合
上限
格式:类型名称 extend 类> 对象名称
说明:只能接收该类型及其子类
下限
格式:类型名称 super 类> 对象名称
说明:只能接收该类型及其父类型
泛型是给javac编译器使用,在编译器编译之后的class文件中是没有泛型信息的,所以泛型的使用不会让程序运行效率收到影响,这个过程称之为擦除。
由于类型擦除了,为了维持多态性,需要一些桥接方法类保持多态性,桥接方法是编译器自动生成的
// 最初的代码
public class Node<T> {
public T data;
public void setData(T data) {
this.data = data;
}
}
public class MyNode extends Node<Integer> {
public void setData(Integer data) {
//....
}
}
// jvm不认识泛型的,把泛型擦除掉, 兼容⽼版本jdk
public class Node {
public Object data;
public void setData(Object data) {
this.data = data;
}
}
public class MyNode extends Node {
// 桥接⽅法,编译器⾃动⽣成
public void setData(Object data) {
setData((Integer)data)
}
public void setData(Integer data) {
//....
}
}
/**
* 测试类
* 通配符的上限 List extends Type>
* 格式:类型名称 extends 类> 对象名称
* 意义:只能接收该类型及其子类
*
* @author : kwan
* @version : 1.0.0
* @date : 2022/8/11 16:57
*/
public class Collection_02_extends_super {
public static void main(String[] args) {
List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog());
// 编译器只知道animals里保存的是Animal的子类
//但是并不知道是哪个子类
//Animal 是接口 ,无法添加
List<? extends Animal> animals = dogs;
// animals.add(new Dog()); // 编译不通过
// animals.add(new Animal()); // 编译不通过
//
Animal animal = animals.get(0);
// Dog dog = animals.get(0); // 编译不通过
}
}
/**
* 测试类
* 通配符的下限 List supper Type>
* 格式:类型名称 supper 类> 对象名称
* 意义:只能接收该类型及其父类
*
* @author : kwan
* @version : 1.0.0
* @date : 2022/8/11 16:57
*/
public class Collection_03_extends_super {
public static void main(String[] args) {
List<Dog> as = new ArrayList<>();
as.add(new Dog());
// 编译器只知道bs里保存的是BigDog的父类
List<? super BigDog> bs = as;
// bs.add(new Dog()); // 编译不通过
bs.add(new BigDog());
// Dog a = bs.get(0); // 编译不通过
// BigDog b = bs.get(0); // 编译不通过
}
}