@TOC
泛型
泛型是在不确定集合中元素的数据类型的时候,可以使用泛型。
泛型可以被看做为一个变量,用来接收数据类型。
泛型在集合被创建的时候确定。
比如:
Collection collection = new ArrayList<>();
这时String会作为参数被传递,从而泛型被改变为String。
使用泛型的好处
不使用泛型的好处:
集合不使用泛型,默认类型是object类型,可以存储任意类型的数据。
弊端:
不安全,会引发异常。
使用泛型的好处:
1.避免了类型转换的麻烦,存的是什么类型,取出的就是什么类型。
2.把运行期异常提升到了编译期异常。
弊端:
泛型是什么类型,只能存储什么类型的数据(可以忽略)。
定义含有泛型的类
泛型定义在类名之后花括号之前。
格式:
public class Student<E>{
private E name;//成员变量
public E getName(){
return name;//成员方法
}
public void setName(E name){
this.name = name;//含参成员方法
}
}
这时在使用这个类时需要指定数据类型,不指定则默认为object。
定义含有泛型的方法
泛型定义在方法的修饰符合返回值类型之间。
格式:
修饰符 <泛型> 返回值类型 方法名(参数列表(使用泛型)){
方法体;
}
含有泛型的方法,在调用方法的时候确定泛型的数据类型,传什么类型的参数,泛型就是什么类型。
定义含有泛型的接口
格式与类定义相似。
使用方法有两种:
1.实现类在实现接口时,指定实现类泛型的具体类型,那么它重写接口的方法时,泛型就是指定的数据类型。
2.实现类的泛型跟着接口的泛型走,接口时什么,实现类就是什么,那么它重写接口的方法时,泛型就是接口的泛型。
泛型通配符
?:代表任意的数据类型。
使用方式:不能在定义时使用,只能作为方法的参数传递使用。
注意:泛型没有继承概念。
受限泛型
在java中泛型是可以指定上下限的。
泛型的上限:
格式:类名 <? extends 类> 对象名
意义:只能接收该类型及其子类。
泛型的下限:
格式:类名 <? super 类> 对象名
意义:只能接收该类型及其父类。
例如:
已知Integer,String,Number,Object四个类。继承关系如下:
Integer extends Number extends Object
String extends Object
public static void main(String[] args){
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement1(list1);
getElement1(list2);//报错
getElement1(list3);
getElement1(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
public static void getElement1(Collection<?> extends Number coll){}
public static void getElement2(Collection<?> super Number coll){}