javaSE进阶-泛型
泛型概述
- 它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
- 它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数
- 参数化类型:就是将类型由 原来具体的类型 参数化 ,然后再使用/调用时传入具体的类型
- 这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
泛型定义格式
-
<数据类型>:指定一种类型的格式,这里的类型可以看作是形参。
List list= new ArrayList<>();
Student是一个实体类,在这里可以将它看成是一个形参 -
<数据类型1,数据类型2>:指定多种类型的格式,中间用逗号隔开。这里的数据类型也可以看成形参
-
将来调用时候给定的类型可以看成是实参,并且实参的类型只能是引用类型
这里创建了一个Set,泛型是Student类型的
Set<Student> ts= new TreeSet<>();
我们实例化Student对象
Student zhangsan = new Student("zhangsan",85,90);
要想Student对象存储到Set集合中,
添加时就得添加对象的变量名,即引用类型
ts.add(zhangsan);
不使用泛型来存储遍历元素
我们创建集合时,并没有使用泛型,我们添加元素时,可以看到提示add(object e),当我们没有指定集合中元素的类型时
,它默认是object类型,因为泛型默认是引用类型,而object指代所有引用类型
因为我们没有指定集合中元素的类型,它默认是object类型
,所以我们接收时也需要使用object类型接收
使用泛型来存储遍历元素
泛型类
定义格式:
- 格式:修饰符 class 类名<类型>{}
- 范例:public class Teacher{}
此处T可以随便写为任意标识,常见的T、E、K、V等形式的参数常用与表示泛型
普通类与泛型类的区别
普通类
如图,普通类中设置了私有属性String类型的name变量,
所以实例化对象后,实参也必须是String类型的,Integer类型的则报错
泛型类
我们类名后面使用了泛型,T指代泛型,具体是哪种泛型,我们在实例化对象声明即可,这样实例化时,存储的数据类型可以是不同的!
泛型方法
- 格式:修饰符<泛型> 返回值类型 方法名(类型 变量名){}
- 范例:public void show(T t){}
我们在实例化对象后,调用泛型方法时,只要实参的数据类型不同,就可以多次调用泛型方法,方法的重载
泛型接口
定义格式:
- 格式:修饰符 intergace 接口名<泛型>{}
- public interfacr Police{}
泛型接口需要实现类来实现这个接口,所以实现类也定义成泛型的,里面的show方法,我们定义也是泛型,但是你实现类实例化后的数据类型是String类型的,那么show方法里的泛型也是String类型
类型通配符
类型通配符:<?>
-
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
这种带通配符的的List仅表示它是各种泛型List的父类,并不能吧元素添加到其中
-
类型通配符上线:<? extends 类型>
List<? extends Number>:它表示的类型是子类型或者Number类型(定义该通配符最高上限为Number,比Number高的类型则不允许)
-
类型通配符下限: <? super 类型>
List<? super Number>: 它表示的类型是Number或者其父类型(定义该通配符最低下限为Number,比Number低的类型则不允许)