1.泛型的定义
泛型即 类型参数。
1.1 含有泛型的类
泛型的定义:
权限修饰符 class 类名<代表泛型的变量> {
}
例如,API中的ArrayList集合:
public class ArrayList<E>{
public boolean add(E e){
}
public E get(int index){
}
....
}
泛型的使用:
在创建对象的时候确定泛型是什么类型。
ArrayList<String> list = new ArrayList<String>();
此时,变量E的值就是String类型,那么我们的类型就可以理解为:
class ArrayList<String>{
public boolean add(String e){
}
public String get(int index){
}
...
}
1.2 含有泛型的方法
定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){
}
public class MyGenericMethod {
public <MVP> void show(MVP mvp) {
System.out.println(mvp.getClass());
}
public <MVP> MVP show2(MVP mvp) {
return mvp;
}
}
1.3 含有泛型的接口
定义格式:
public interface MyGenericInterface<E>{
public abstract void add(E e);
public abstract E getE();
}
使用格式:
1、定义接口的实现类时 确定泛型的类型
public class MyImp1 implements MyGenericInterface<String> {
@Override
public void add(String e) {
// 省略...
}
@Override
public String getE() {
return null;
}
}
2、定义接口的实现类时 先不去明确泛型的类型,直到创建对象时,确定泛型的类型
public class MyImp2<E> implements MyGenericInterface<E> {
@Override
public void add(E e) {
// 省略...
}
@Override public E getE() {
return null;
}
}
确定泛型:
/** 使用 */
public class GenericInterface {
public static void main(String[] args) {
MyImp2<String> my = new MyImp2<String>();
my.add("aa");
}
}
2. 泛型通配符
2.1 通配符基本使用
为什么要用通配符呢?
在java中,数组是可以协变的,比如Dog extends Animal
,那么Animal[] 与Dog[]
是兼容的。
而集合是不能协变的,也就是说List<Animal>
不是 List<dog>
的父类,这时候就可以用到通配符了。
此时只能接受数据,不能往该集合中存储数据。举个例子大家理解使用即可:
public static void main(String[] args) {
Collection<Intger> list1 = new ArrayList<Integer>();
getElement(list1);
Collection<String> list2 = new ArrayList<String>();
getElement(list2);
}
//?代表可以接收任意类型
public static void getElement(Collection<?> coll){
}
2.2 通配符高级使用
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);
}
// 泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll) {
}
// 泛型的下限:此时的泛型?,必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll) {
}