- 什么是泛型
- 代表任意类型(generic:一般的,类的)
- jdk1.5后推出的
- 泛型的作用(也就是产生原因)
- 解决集合类型安全问题(指定集合存储的数据类型)的同时,又减小代码量
- 集合不像数组,存储的数据类型是固定的,因为集合存储的是引用数据类型(类型不定),这在运行时极易发生类型转换异常
- 使用泛型后可将运行期间出现的类型转换异常转移到编译时期,提高开发效率
- 举例
一个list集合如果不用泛型,既能存储Teacher对象又能存储Student对象
但是Teacher对象和Student拥有的属性或方法不同,编码较复杂(比如获取他们特有的属性)
首先得把Object对象强制类型转换成Teacher或Student(这里如果判断不当就会发生类型转换异常)
- 解决集合类型安全问题(指定集合存储的数据类型)的同时,又减小代码量
- 如何使用泛型
-
用在集合中指定集合存储的数据类型
- 语法
集合类型<数据类型> 变量名 = new 集合类型<数据类型>(); - 说明
前后数据类型要一致,或省略后面的数据类型(jdk1.7后支持菱形泛型)
- 语法
-
泛型类
-
它是什么
可是任意类型的类 -
它的作用
能合并多个类的功能:根据构造实例时传递的类型参数决定该类的类型从而执行特定的操作 -
如何使用
语法
修饰符 class 类名<类型参数名1[,类型参数2…,类型参数3]>{}
说明
类型参数名可理解成形式参数,通常以1个大写字母表示
此时这个类的类型不是类名了,而是实例化时传递的类型参数的值
传递的类型参数的值是Object的子类(这个类要存在)
类型参数也称为泛型变量,它可以有多个,多个之间用,隔开
多个泛型变量指定的泛型类用法与一个泛型变量的用法完全相同,只是多了一个类型标识符,实例化时需要多传递一个类型
泛型变量的命名规则
通常使用单个大写字母
E:常用在集合中
K,V用在map映射
T:表示基本类型 -
测试代码
-
-
泛型接口
- 它是什么
- 可以是任意类型的接口
- 它的作用
- 可以合并多个接口的功能:根据实现类传递的类型参数决定接口的类型
- 如何使用
-
语法
interface 接口名<类型参数1[,类型参数2…类型参数3]>{}
修饰符 class 类名 implemests 泛型接口名<类型1[,类型2…类型3]>{}
-
说明
- 泛型接口定义不泛型类定义,形式上相同
- 实现泛型接口时需要传入实际的类型
-
- 测试代码
- 它是什么
-
泛型方法
-
它是什么
可以是任意类型参数的方法 -
它的作用
可以合并多个方法:方法在调用时指定参数类型 -
如何使用
静态泛型方法
语法
访问修饰符 static <类型参数1[,类型参数2…类型参数3]> 返回值类型 方法名(){}
普通方法
语法
访问修饰符 static <类型参数1[,类型参数2…类型参数3]> 返回值类型 方法名(){}
说明
静态仅多个static修饰符,调用时可用类名调用
调用写法
类名或对象名.<实际类型1[,类型…]>方法名(类型值1[,类型值…]);//完整写法的好处:可对参数进行类型判断
类名或对象名.方法名(类型值1[,类型值…]);//调用时可省去类型的指定,由实际参数类型决定
但尽量不要使用这种隐式的传递方式,代码不利于阅读和维护。因为从外观根本看不出来你调用的是一个泛型函数泛型函数处定义的泛型可以用于当作返回值类型,参数类型,反射类型,集合类型,迭代器类型
测试代码
-
-
说明
- 在迭代器中,指定迭代器迭代的数据类型:Iterator<类型>
- 在反射类型中,指定特定的反射类型:Class
字符串的反射类型 - ?通配符:不确定<>是的类型时可以用?表示:可以查,删,不能增,改
-
单用在集合中
- 举例
-
向上限定: <? extends E>
-
向下限定: <? super E>
-
-