- 泛型:是JDK5中引入的特性,可以在编译阶约束操作的数据类型,并进行检查。
2、格式
<数据类型>
-
注意:泛型仅支持引用数据类型。
-
集合体系的全部接口和实现类都是支持泛型的使用。
3、好处、优势
- 统一数据类型。
- 把运行期间的问题提到了编译期间,避免了强制类型转换可能出现的异常,因为编译阶段类型就能确定下来了。
package com.app.d7_genericity; import java.util.ArrayList; import java.util.List; public class GenericityDemo1 { public static void main(String[] args) { // 不用泛型,当你在运行期间,会出现强制类型转换的bug List list1 = new ArrayList<>(); list1.add("Java"); list1.add("赵敏"); list1.add(34.6); list1.add(false); list1.add(343); System.out.println("list1 = " + list1); // 使用泛型,在编译期间已经确定了数据类型,后面需要对数据做处理的话,就不会出现强制类型转换这样的操作了 // Listlist2 = new ArrayList<>(); // 报错!因为泛型仅支持引用数据类型 List list2 = new ArrayList<>(); list2.add(343); list2.add(33); System.out.println("list2 = " + list2); // 报错!因为此集合需要整数类型的数据,给的却是字符串类型 // list2.add("Java"); // list2.add("赵敏"); // 报错!因为此集合需要整数类型的数据,给的却是浮点类型 // list2.add(34.6); // 报错!因为此集合需要整数类型的数据,给的却是布尔类型 // list2.add(false); System.out.println("-----------------------------------"); // 想使用泛型,但是又想存储任意类型的数据 List
list1 = [Java, 赵敏, 34.6, false, 343] list2 = [343, 33] ----------------------------------- list3 = [Java, 赵敏, 34.6, false, 343] Process finished with exit code 0
4、泛型的用武之地
- 类后面——>泛型类。
- 方法申明上——>泛型方法。
- 接口后面——>泛型接口。
二、自定义泛型类 1、概述
- 定义类的同时定义了泛型的类,就是泛型类。
2、格式
修饰符 class 类名<泛型变量>{}
- 范例:
public class MyArrayList{ }
- 此处泛型变量T可以随便写为任意标识,常见的如E、T、K、V等。
3、作用
- 编译阶段可以指定数据类型,类似于泛型在集合中的作用。
4、案例导学
-
模拟ArrayList集合自定义一个集合MyArrayList集合,完成添加和删除功能的泛型设计即可。
package com.app.d8_genericity_class; import java.util.ArrayList; public class MyArrayList
{ private ArrayList package com.app.d8_genericity_class; public class Test { public static void main(String[] args) { // 创建我们自己定义的泛型类:MyArrayList集合 MyArrayList
list1 = new MyArrayList<>(); // 添加元素 list1.add("JavaSE"); list1.add("JavaSE"); list1.add("我的集合"); list1.add("我的集合"); list1.add("你是唯一"); // list1.add(34); // 报错 System.out.println("删除前:" + list1); // 删除元素 list1.remove("JavaSE"); System.out.println("删除后:" + list1); System.out.println("--------------------------------"); MyArrayList list2 = new MyArrayList<>(); list2.add(45.3); list2.add(99.0); list2.add(1034.54); System.out.println("删除前:" + list2); list2.remove(45.3); System.out.println("删除后:" + list2); } } 删除前:[JavaSE, JavaSE, 我的集合, 我的集合, 你是唯一] 删除后:[JavaSE, 我的集合, 我的集合, 你是唯一] -------------------------------- 删除前:[45.3, 99.0, 1034.54] 删除后:[99.0, 1034.54] Process finished with exit code 0
5、原理
-
把出现泛型变量的地方全部替换成传输的真实数据类型。
总结
1、泛型类的核心思想是什么?
- 把出现泛型变量的地方全部替换成传输的真实数据类型。
2、泛型类的作用是什么?
- 编译阶段约定操作的数据的类型,类似于泛型在集合中的作用。
三、自定义泛型方法 1、概述
- 定义方法的同时定义了泛型的方法,就是泛型方法。
2、格式
修饰符 <泛型变量> 方法返回值 方法名(形参列表){ }
- 范例:
publicvoid show(T t){ }
3、作用
- 方法中可以使用泛型接收一切实际类型的参数,方法更具备通用性。
4、案例导学
-
给你任何一个类型的数组,都能返回它的内容。也就是实现Arrays.toString(数组)的功能!
package com.app.d9_genericity_method; import java.util.Arrays; public class Test { public static void main(String[] args) { // 1、定义两个不同类型的数组,随便传入两组数据 String[] names = {"赵敏", "小昭", "周芷若"}; Double[] scores = {99.0, 59.9, 69.5, 100.0}; printArrays(names); printArrays(scores); Integer[] arrTest1 = {}; Integer[] arrTest2 = null; printArrays(arrTest1); printArrays(arrTest2); } public static
void printArrays(T[] arr){ if (arr != null) { // 不为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); // 为null,输出空数组变量 } } } [赵敏, 小昭, 周芷若] [99.0, 59.9, 69.5, 100.0] [] null Process finished with exit code 0
5、原理
- 把出现泛型变量的地方全部替换成传输的真实数据类型。
总结
1、泛型方法的核心思想是什么?
- 把出现泛型变量的地方全部替换成传输的真实数据类型。
2、泛型方法的作用是什么?
- 方法中可以使用泛型接收一切实际类型的参数,方法更具备
四、自定义泛型接口 1、概述
- 使用了泛型定义的接口,就是泛型接口。
2、格式
修饰符 interface 接口名<泛型变量>{ }
- 范例:
public interface Data{ }
3、作用
- 泛型接口可以让实现类选择当前功能需要操作的数据类型。
4、案例导学
- 教务系统,提供一个接口可约束一定要完成数据(学生,老师)的增删改查操作。
5、原理
-
实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对于该类型的操作。
总结
1、泛型接口的作用是什么?
- 泛型接口可以约束实现类,实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对于该类型的操作。
五、泛型通配符、上下限 1、通配符:?
- ?:可以在 “使用泛型” 的时候代表一切类型。
2、通配符:E、T、K、V
- E、T、K、V:是在定义泛型的时候使用的。
3、案例导学
- 模拟开发一个极品飞车游戏,所有的汽车都能一起参与比赛。
- 注意:虽然BMW和BENZ都继承了Car,但是ArrayList< BMW>和ArrayList< BENZ>与ArrayList< Car>之间半毛钱关系都没有!!
-
泛型的上下限:
-
? extends Car:? 必须是Car或者其子类(泛型上限)。
-
? super Car:? 必须是Car或者其父类(泛型下限)。
-