1. 前言
· 本文章是用于 个人学习过程中 整理知识点的帖子,主题为:JavaSE 泛型 入门
· 本文章出现的 遗漏、错误 欢迎点开这篇文章的各位指出。
· 本文章的知识大纲根据 韩顺平老师 JavaSE 教学视频 进行编写。
【感谢韩顺平老师带来的优质教学和对教育作出的贡献】
2. 泛型的引入
● 场景模拟 ●
· 定义一个ArrayList对象,在里面添加Dog类,并进行迭代遍历。
· 此时如果不慎将一个Cat类型的对象添加进来,就会发生 ClassCastException
异常。
· 会发生这样的异常错误,是因为 数据类型不统一 导致的。
· 在日常开发中,如果放大这样的疏漏,后果将会十分严重,我们需要在添加数据时 约束传入的类型 。
· 于是我们引入了 泛型 的概念。我们先来看看泛型的使用效果:
· 我们可以看到,当我们设置当前ArrayList对象的泛型是Dog类型时,就会阻止添加Cat类型的对象。
· 下面我们就来详细介绍 泛型 。
3. 基本介绍
● 基本介绍 ●
· 泛型,又称 参数化类型。它是 JDK 5 版本中出现的新特性,目的是为了 解决数据类型的安全性问题 。
· 泛型可以保证程序在编译时没有发出警告,运行时就不会产生异常 。
· 泛型的作用:可以在声明对象时,通过一个标识标识类的各种成员。
● 相关细节 ●
① 定义方面:
· 泛型的类型 只能是引用类型 。
· 使用泛型的数组 不能初始化 。
· 在给泛型定义具体的数据类型后,可以传入 该类型 或者 其子类型 。
· 在创建定义泛型的类对象,却没有指定泛型具体数据类型时,默认类型是 Object 类型 。
② 结构方面:
· 静态方法中 不能使用 类的泛型 。
· 普通成员可以使用泛型。例如:属性、方法 。
③ 创建方面:
· 泛型的使用形式,有以下 两种方法:
a. 基础写法:ArrayList<Integer> list = new ArrayList<Integer>();
b. 简洁写法:ArrayList<Integer> list = new ArrayList<>();
4. 泛型的语法
● 迭代对象 ●
· 我们分别通过 HashSet、HashMap 遍历 Student 类 来感受泛型的语法。
· 我们在编译 HashSet 和 HashMap 迭代方法时,会发现:迭代器 和 EntrySet 对象 都进行了泛型声明 。
· 这是因为 HashSet 和 HashMap 这两个类都是 自定义泛型类,在执行包含 泛型参数、属性 的方法时,系统会自动填充声明对象的泛型。
● HashSet 类 & add 方法 & 迭代器 ●
● HashMap 类 & put 方法 & entrySet 方法 ●
· 下面将详细讲解 自定义泛型 。
5. 自定义泛型
自定义泛型有三种常用类型:泛型类、泛型接口、泛型方法 。
● 泛型类 ●
语法结构:class A<E,T,Z,K...>{}
【一个类可以定义多个泛型】
● 泛型接口 ●
语法结构:interface A<E,T,Z,K...>{}
【一个接口可以定义多个泛型】
相关细节:泛型接口的类型是在 实现 或 继承 泛型接口时确定的。
● 定义 泛型接口 ●
● 实现 泛型接口 定义泛型类型 ●
● 继承 泛型接口 定义泛型类型 ●
● 泛型方法 ●
语法结构:修饰符 <T,R..> 返回类型 方法名(参数列表){}
相关细节:
· 泛型方法可以定义在 普通类 和 泛型类 中 。
· 在调用泛型方法时就需要定义泛型的具体数据类型 。
· 我们在调用 Car 对象 中 drive 方法 时,传入的参数就是泛型的类型,此时会根据传入的类型装箱成指定数据类型 。
5. 泛型的继承 & 通配符
· 泛型本身是不具有继承机制的,例如:ArrayList<Object> list = new ArrayList<String>();
是错误的。
· 在开发中,开发人员可以 约束泛型的范围,也就是设定当前泛型的 上限和下限 。
· 泛型通配符包含以下类型:
① <?> : 支持任意泛型类型
② <? extends A> : 支持A类以及A类的子类,规定了泛型的上限
① <? super A> : 支持A类以及A类的父类,不限于直接父类,规定了泛型的下限