泛型
1. 认识泛型
定义类、接口、方法时,同时声明了一个或多个类型变量(如:),称为泛型类、泛型接口、泛型方法、它们统称为泛型。
2. 泛型类
public class Test {public static void main(String[] args) {MyArrayList<String> list = new MyArrayList<>();System.out.println(list.add("Jack")); // trueSystem.out.println(list.get(0)); // Jack}
}// 自定义一个泛型类,去模拟 ArrayList
class MyArrayList<E> { // 如果不想规范地写,其实E也可以写成其他字母private Object[] arr = new Object[10]; // 容器,用来装东西private int size; // 记录当前装了多少个public boolean add(E content) {arr[size++] = content;return true;}public E get(int index) {return (E) arr[index];}
}
public class Test {public static void main(String[] args) {MyClass<String, String> obj = new MyClass<>();obj.put("只能是String类型", "只能是String类型");
// Others<String> obj1 = new Others<>(); // 报错Others<MyClass> obj2 = new Others<>(); // 正常System.out.println(obj2.age); // 输出结果:0}
}class MyClass<E, T> {public void put(E e, T t) {}
}// 要求 E 的类型是继承 MyClass 或者 E 的类型是 MyClass
class Others<E extends MyClass> {public int age;
}
3. 泛型接口
- 注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
import java.util.ArrayList;public class Test {public static void main(String[] args) {}
}class Student {}class Teacher {}// 泛型接口
interface Data<E> {void add(E obj);ArrayList<E> getByName(String name);}// 实现类
class StudentData implements Data<Student> {@Overridepublic void add(Student obj) {}@Overridepublic ArrayList<Student> getByName(String name) {return null;}
}// 实现类
class TeacherData implements Data<Teacher> {@Overridepublic void add(Teacher obj) {}@Overridepublic ArrayList<Teacher> getByName(String name) {return null;}
}
4. 泛型方法
案例一
public class Test {public static void main(String[] args) {System.out.println(get(10)); // 10System.out.println(get("Java")); // JavaSystem.out.println(get(new A())); // 对象的内存地址: login.A@3b07d329}// 泛型方法public static <T> T get(T name) {return (T) name;}// 泛型方法public static <E> void run(E index) {}
}class A {}
案例二
通配符:就是" ? ",可以在"使用泛型"的时候代表一切类型;E T K V 是在定义泛型的时候使用
import java.util.ArrayList;public class Test {public static void main(String[] args) {// 需求:实现所有的汽车都能一起参加比赛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());go(bmws);ArrayList<BENZ> benzs = new ArrayList<>();benzs.add(new BENZ());benzs.add(new BENZ());go(benzs);ArrayList<Dog> dogs = new ArrayList<>();dogs.add(new Dog());dogs.add(new Dog());
// go(dogs); // 报错}// <T>是没有限制数据类型的泛型,如果我们加一个限制条件,不要让狗类进来,可以这样写:<T extends Cars>,完整代码如下一行所示public static <T extends Car> void go(ArrayList<T> allCars) {}// 知识扩展:// ? 是通配符,在使用泛型的时候可以代表一切类型" ? extends Car "【上限】 " ? super Car "【下限】
// public static void go1(ArrayList<? extends Car> allCars) {}
// public static void go2(ArrayList<? super Car> allCars) {}
}class Car {}class BMW extends Car {}class BENZ extends Car {}class Dog {}
5. 注意事项
- 泛型是工作在编译阶段的,一旦程序编译成 class 文件,class 文件中就不存在泛型了,这就是泛型擦除。
- 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)
import java.util.ArrayList;public class Test {public static void main(String[] args) {
// ArrayList<int> list1 = new ArrayList<>(); // 报错ArrayList<Integer> list2 = new ArrayList<>(); // 正常}
}