泛型:
是一种未知数据类型,当不知道使用什么数据类型,可以使用泛型。
也可以看作一种变量
E e: Element元素
T t: Type类型
ArrayList
函数:
不知道接收什么数据,使用element接收。
创建集合对象时,才会确定泛型的数据类型
ArrayList list = new ArrayList();
//不写<>集合类型,默认为object
不使用泛型:
- 在一个ArrayList中存入多种类型 对象
- 在对对象进行操作,可能会因类型不同出现错误
使用泛型:
- 避免转换类类型麻烦,存什么取什么
- 把运行期的异常,提前到了编译期
public class GenericClass<E>{
private E name;
public E getName(){
return name;
}
public void setName(E name){
this.name = name;
}
}
在类中使用泛型方法,类名后加
<E>
,类中变量类型和方法返回类型全写为
E
。
创建对象的时候在名称后加
<类型>
避免用泛型方法进行重载
重载和使用泛型的区别:
- 重载是多个方法名相同,方法传参不同,方法内容不同
- 泛型只是在传入参数的时候规定参数类型。
使用泛型的类格式
修饰符 class 类名<泛型> {...}
class ArrayList<E>{
public boolean add(E e){}
public E get(int index){}
...
}
使用泛型的方法格式
使用泛型的方法,在调用方法的时候确定泛型的数据类型
修饰符<泛型> 返回值类型 方法名(参数列表(使用泛型)){方法体}
public class MyClass{
public <M> void show(M m){
System.out.println(m.getClass());
}
}
//调用方法时,确定泛型的类型
public class MyClassTest{
public static void main(String[] args){
MyClass mc = new MyClass();
mc.show(1);
mc.show("string");
}
}
使用泛型的接口格式
泛型通配符
只在方法的参数中使用,创建通用参数类型,可以接收不同种类的类型
?
:代表任意数据类型
使用方式:
不能创建对象使用
ArrayList<?> list = new ArrayList<?>()// 不可以
只能作为方法的参数使用
使用情况举例:
定义一个方法,遍历所有ArrayList
不知道使用的什么类型,可以用泛型通配符?来接收数据
泛型没有继承概念 ArrayList<不能能写父类>
// 接收任意类型输入
public static void printArray(ArrayList<?>, list){
//使用迭代器遍历集合
Iterator<?> it = list.iterator();
while(it.hasNext()){
//object可以接受任意类型数据
Object o = it.next();
System.out.println(o);
}
}
泛型上限下限
- 泛型上限限定:?extends E 使用泛型只能是E类型的子类/本身
- 泛型下限限定:?super E 使用泛型只能是E类型的父类/本身
继承关系:
Integer extends Number extends Object
String extends Object
//传入类型只能是Number类型或者Number的子类
...(Collection<? extends Number> coll){}
//传入类型只能是Number类型或者Number的父类
...(Collection<? super Number> coll){}