泛型的概述:
- 定义类同时定义了泛型的类就是泛型类。
- 泛型的格式:修饰符 class 类名<泛型变量>{}
- 此处泛型变量T可以随便写为任意标识,常见的如E、T、K、V等。
泛型类的原理:
- 把出现泛型变量的地方全部替换成传输的真实数据类型。
泛型方法的概述
- 定义方法同时定义了泛型的方法就是泛型方法。
- 泛型方法的格式:修饰符<泛型变量> 方法返回值 方法名称(形参列表){}
- 作用:方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性。
泛型方法的原理:
- 把出现泛型变量的地方全部替换成传输的真实数据类型。
代码掩饰如下:
public class GenericDemo { public static void main(String[] args) { String[] names = {"鸟儿","小鸟","大鸟"}; printArray(names); Integer[] ages = {10,20,30}; printArray(ages); } public static <T> void printArray(T[] arr){ if (arr != null){ StringBuilder sb = new StringBuilder("["); for (int i = 0; i < arr.length; i++) { sb.append(arr[i]).append(i == arr.length - 1 ? "" : ","); } sb.append("]"); System.out.println(sb); }else{ System.out.println(arr); } } }
泛型接口的概述
- 使用了泛型定义的接口就是泛型接口。
- 泛型接口的格式:修饰符 interface Date<E>{}
- 作用:泛型接口可以让实现类选择当前功能需要操作的数据类型
泛型接口的原理:
- 实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将针对于该类型的操作。
代码演示如下:
接口:
public interface Date<E> { void add(E e); void delete(int id); void update(E e); E queryByID(int id); }
学生类:
public class Student { }
学生数据:
public class StudentDate implements Date<Student> { @Override public void add(Student student) { } @Override public void delete(int id) { } @Override public void update(Student student) { } @Override public Student queryByID(int id) { return null; } }
通配符:?
- ?可以在“使用泛型”的时候代表一切类型。
- E T K V 是在定义泛型的时候使用的。
代码演示如下:
public class GenericDemo {
public static void main(String[] args) {
ArrayList<BENZ> benzs = new ArrayList<>();
benzs.add(new BENZ());
benzs.add(new BENZ());
benzs.add(new BENZ());
go(benzs);
}
/**
所有车比赛
*/
public static void go(ArrayList<?> cars){
}
}
class BENZ extends Car{
}
class BMW extends Car{
}
//父类
class Car{
}
泛型的上下限:
- ?extends Car:?必须是Car或者其子类 泛型上限
- ?super Car:?必须是Car或者其父类 泛型下限
例如代码中,extends Car 后,狗类就无法进来了。