1、泛型引入
泛型:用在不确定数据类型的时候(定义泛型)。
书写而格式:<数据类型>这里的数据类型必须是类类型或者接口类型,不能是基本数据类型。
运行>>>>>
上面的程序,在运行的时候发生了类型转换异常。
发生异常的原因:
在集合中保存的数据有String类型,也有Integer类型。在取出数据的时候,并没有做任何的判断,直接将取出的数据转成String
当取出的是Integer的时候,是无法转成String类型,就会发生上面的异常。
小编是一个有着5年工作经验的java程序员,对于java,自己有做资料的整合,一个完整学习java的路线,学习资料和工具,相信这里有很多学习java的小伙伴,我创立了一个2000人学习扣群,479121291。每晚都有java的直播课程。无论是初级还是进阶的小伙伴小编我都欢迎!
解决方案:
1、取出的时候,对数据类型进行判断。
2、在给集合保存数据的时候,就让集合中只能保存String类型数据,如果保存了其他的数据,让在编译的时候就报错。
上述的第二种解决方案:类似于数组
int[] arr = new int[6];
arr[0] = 123;
arr[1] = 3.14; 数组在定义的时候,就已经限定了每个空间只能存放int类型的数据,无法保存double类型的数据。
使用上述的方式解决集合,只需要在定义集合的时候在集合上加上数据类型的限定即可。这个技术就是泛型技术。
2、泛型技术介绍
泛型的书写格式:
<类或接口类型>
注意:在使用泛型的时候,一定是原来的类或者接口中预留的需要书写泛型的代码。如果类或接口中没有声明让书写泛型,在我们的代码中坚决不能出现泛型。
3、泛型技术简单应用
案例:给TreeSet集合传递比较器,比较String类型数据的长度。
4、自定义泛型
4.1 、在类上定义泛型
常规的类定义格式:
修饰符 class 类名{
成员;
}
定义泛型类格式:
修饰符 class 类名<标识符>{
成员;
}
注意:在类上定义的泛型,在使用这个类的时候,需要指定具体的数据类型,如果没有指定,这个泛型默认就会变成Object类型。
在类上定义的泛型,当使用的时候明确之后,类中所有使用和类上相同名称的泛型标识符的地方,都会转成当前给指定的数据类型。
4.2、非静态方法上定义泛型
有时定义类上的泛型,在类中的方法上使用的数据和其不一致。
在类中定义普通方法的格式:
修饰符 返回值类型 方法名( 参数列表 ){
方法体
}
定义拥有泛型的方法格式:
修饰符<标识符>返回值类型 方法名( 参数列表 ){
方法体
}
方法上定义的泛型,必须书写在返回值类型的前面。
4.3、静态方法上定义泛型
4.4、接口上定义泛型
接口的定义格式:
修饰符 interface 接口名{
成员;
}
泛型接口的定义格式:
修饰符 interface 接口名<标识符>{
成员;
}
总结:接口上的泛型,在定义接口的实现类的时候明确。
4.5.泛型传递
interface Collection<E>{}
interface List<E> extends Collection<E>{}
class ArrayList<E> implments List<E>{}
上述的这种泛型的关系,称为泛型传递,最终需要使用这个实现类对象的程序去明确泛型的具体数据类型。
5、泛型限定
5.1.泛型通配符
通配符:使用某些符号代替其他的信息或者数据。
泛型的通配符号:?
5.2.泛型上下限
需求:定义通用的打印不同集合中元素的方法
5.3.API中泛型限定介绍
TreeSet源码的定义格式:
public class TreeSet<E>{
public TreeSet( Collection< ? extends E> c ){
}
public TreeSet( Comparator< ? super E> com ){
}
}
//创建TreeSet集合对象
TreeSet<Person> set = new TreeSet< Person >( );
TreeSet类上定义的泛型E 已经被Person代替。TreeSet类中的方法中使用的E也为Person。
在创建TreeSet集合的时候,可以传递一个Collection集合,作为TreeSet集合中的初始化元素。
Set<Student> s = new HashSet<Student>(); 假设HashSet中已经添加了部分的Student对象
TreeSet<Person> set = new TreeSet< Person >( s );通过public TreeSet( Collection< ? extends E> c ) 创建TreeSet集合,
并传递初始化数据,而在创建TreeSet集合的时候,限定集合中保存的元素是Person,那么指定传递数据的
集合中的元素也应该和Person有一定的关系。
构造方法中接收的参数上的? extends E 相当于 ? extends Person。
当前给TreeSet中传递数据的集合中的元素必须是Person或者Person的子类。
public TreeSet( Comparator< ? super E> com ) 构造方法上传递的Comparator的目的是对TreeSet中保存的元素进行大小比较的。
真正给TreeSet中保存的任何元素都需要先取出来交给比较器进行大小的比较,然后决定具体存放的位置。