泛型
概述
只支持引用类型。
可以再编译阶段约束操作的数据类型,并进行检查。
集合体系的全部接口和实现类都是支持泛型的使用的。
好处
统一数据类型。
把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为编译阶段类型就能确定下来。
1. 自定义泛型类
泛型类的概述
定义类时同时定义了泛型的类就是泛型类。
泛型类的格式:修饰符 class 类名<T> { ...... }
作用:编译阶段可以指定数据类型,类似于集合。
泛型类的原理:把出现泛型变量的地方全部替换成传输的真实数据类型。
1 import java.util.ArrayList; 2 3 public class genericityClassDemo1<E> { 4 private ArrayList lists = new ArrayList<>(); 5 6 public void add(E e) { 7 // 用官方的方法,实现自己 自定义的泛型类 8 lists.add(e); 9 } 10 11 public void remove(E e) { 12 // 用官方的方法,实现自己 自定义的泛型类 13 lists.remove(e); 14 } 15 16 @Override 17 public String toString() { 18 19 return lists.toString(); 20 } 21 }
1 public class testDemo1 { 2 public static void main(String[] args) { 3 genericityClassDemo1<String> list = new genericityClassDemo1<>(); 4 list.add("phx"); 5 list.add("wl"); 6 list.add("java"); 7 8 list.remove("java"); 9 System.out.println(list); 10 } 11 }
2. 自定义泛型方法
定义方法时同时定义了泛型的方法。
格式:修饰符 <泛型变量> 泛型返回值 方法名称( 形参列表 ){ ....... }。
方法中可以使用泛型接收。
核心思想:把出现泛型变量的地方全部替换成传输的真实数据类型。
1 public class GenericityMethodDemo { 2 public static void main(String[] args) { 3 String[] names = {"phx", "wl"}; 4 Integer[] ages = {23, 22}; 5 6 PrintArray(names); 7 PrintArray(ages); 8 } 9 /** 10 * T 是通配符 11 */ 12 public static <T> void PrintArray(T[] arr) { 13 if (arr != null) { 14 StringBuffer s = new StringBuffer("["); 15 for (int i = 0; i < arr.length; i++) { 16 s.append(arr[i]).append(i == arr.length - 1 ? "" : ","); 17 } 18 s.append("]"); 19 System.out.println(s); 20 }else { 21 System.out.println(arr); 22 } 23 } 24 }
3. 自定义泛型接口
格式:修饰符 interface 接口名称 <泛型变量> { ...... } 。
作用:泛型接口可以让实现类选择当前功能需要操作的数据类型。
原理:实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对于该类型的操作。
4. 泛型通配符、上下限
通配符: ? 可以在使用泛型的时候代表一切类型。
ETKV是在定义泛型的时候使用的。
1 public class GenericDemo { 2 public static void main(String[] args) { 3 4 ArrayList<BMW> bmws = new ArrayList<>(); 5 //封装 6 bmws.add(new BMW()); 7 bmws.add(new BMW()); 8 go(bmws); 9 10 ArrayList<BENZ> benzs = new ArrayList<>(); 11 benzs.add(new BENZ()); 12 benzs.add(new BENZ()); 13 go(benzs); 14 15 } 16 17 /** 18 * ? extends Car 必须是Car或者其子类,泛型上限 19 * ? super Car 必须是Car或者其父类,泛型下限 20 * 如果只用 ? 会导致什么都传的进去 21 */ 22 public static void go(ArrayList<? extends Car> cars) { 23 24 } 25 } 26 27 class BENZ extends Car { 28 29 } 30 31 class BMW extends Car { 32 33 } 34 35 class Car { 36 37 }