定义类、接口、方法时,同时声明了一个或者多个类型变量(如:),称为泛型类、泛型接口,泛型方法、它们统称为泛型。
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力。这样可以避免强制类型转换,及其可能出现的异常。
泛型的本质:把具体的数据类型作为参数传给类变量。
自定义泛型类
自定义泛型接口
自定义泛型方法
eg. 模拟ArrayList类
//泛型类
//这里的E,使用A、B、C都是一样的,一般使用E、T、K、V
public class MyArrayList<E> {
private Object[] arr = new Object[10];
private int size; //记录当前位置的
public boolean add(E e) {
arr[size++] = e;
return true;
}
public E get(int index) {
return (E) arr[index];
}
}
//泛型类
//这里的E,使用A、B、C都是一样的,一般使用E、T、K、V
public class MyClass<E, T> {
public void put(E e, T t) {
}
}
//泛型类3
//在使用时这里的E必须要是继承Animal类的类才可以放进来
//泛型类可以通过extends的方式来限制放入的类型变量
public class MyClass3<E extends Animal> {
}
public class Dog extends Animal {
}
//会报错,因为String类型没有继承Animal
MyClass3<String> c3 = new MyClass();
//正确,可以放入Animal本身
MyClass3<Animal> c3 = new MyClass();
//正确,因为Dog继承了animal
MyClass3<Dog> c3 = new MyClass();
eg.
场景:系统需要处理学生和老师的数据,需要提供2个功能:
保存对象数据,
根据名称查询数据。
//老师类
public class Teacher {
}
//学生类
public class Student {
}
//泛型接口
public interface Data<T> {
void add(T t);
ArrayList<T> getByName(String name);
}
//实现类
public class TeacherData implements Data<Teacher> {
@Override
public void add(Teacher teacher) {
}
@Override
public ArrayList<Teacher> getByName(String name) {
return null;
}
}
//实现类
public class StudentData implements Data<Student> {
@Override
public void add(Student student) {
}
@Override
public ArrayList<Student> getByName(String name) {
return null;
}
}
public class Test {
public static void main(String[] args)
}
public static <T> T test(T t) {
return t;
}
//正确
test(new Dog());
test("java");
eg
需求: 所有的汽车可以一起参加比赛
public class Car {
}
public class BMW extends Car {
}
public class BENZ extends Car {
}
public static void go(ArrayList<Car> cars) {
}
ArrayList<Car> cars = new ArrayList<>();
cars.add(new BMw());
cars.add(new BENZ());
go (cars);
ArrayList<BMW> bmws = new ArrayList<>();
//加入两辆宝马车
bmws.add(new BMW());
bmws.add(new BMW());
//会报错,重点:Car是父类,但ArrayList的Car和ArrayList的BMW是没有关系的
go(bmws);
解决方法
//这样所有类型的ArrayList都可以送进来
public static <T> void go(ArrayList<T> cars) {
}
//仅限定汽车能进来
public static <T extends Car> void go(ArrayList<T> cars) {
}
//ArrayList本身就是泛型,?是通配符,在使用泛型时可以代表一切类型
public static void go(ArrayList<?> cars) {
}
//加入限定
// ? extends Car(上限) 必须是Car或Car的子类
// ? super Car(下限) 必须是Car或Car的父类
//此时可以送入的类型是Car以及Car的子类
public static void go(ArrayList<? extends Car> cars) {
}
class底层中帮你强转类型
引用类型都是Object的子类,而基本类型不是类。