目录
什么是泛型
泛型的本质是参数化类型。它指的是一个未知的数据类型。当我们创建对象的时候会确定泛型的数据类型。泛型的数据类型一经确立,必须都要用统一的类型。另外,泛型只能是引用类型或包装类不能是基本类型 。
使用泛型的好处
- 不使用泛型
以集合为例。集合不使用泛型,默认的类型就是Object类型,可以存储任意类型的数据。但如果集合中既有字符串也有数值,你就不能使用字符串特有的方法,因为多态不允许使用子类特有的方法,这时数值类型就会出现类型转换异常。集合中不使用泛型是不安全的
- 使用泛型
无需类型转换,因为集合中只能存储唯一的数据类型。这样就把程序运行期的异常提升到了编译期。
定义和使用含有泛型的类
这样定义只有当创建对象的时候才用确定数据类型,提高了灵活性。
//定义
public class GenericClass<E> {
private E name;
public E getName() {
return name;
}
public void setName(E name) {
this.name = name;
}
}
//使用
GerericClass<Integer> gc = new GerericClass<>();
gc.setName(1);
定义和使用含有泛型的方法
这样定义在调用泛型方法的时候才确定这个方法的数据类型
//定义
public class GenericMethod {
public <E> void method01(E e) {
System.out.println(e);
}
public static <E> void method02(E e) {
System.out.println(e);
}
}
//使用
GenericMethod gm = new GenericMethod();
gm.method01("abc");
GenericMethod.method02("abc");
定义和使用含有泛型的接口
定义和使用泛型的接口有两种方式。区别就在于实现类实现的是接口的泛型,还是接口自定义的泛型。
//定义接口
public interface GenericInterface<I> {
public abstract void method(I i);
}
//接口实现类
public class GenericInterfaceImpl1 implements GenericInterface<String> {
@Override
public void method(String s) {
System.out.println(s);
}
}
//使用实现类中的方法
public class Demo {
public static void main(String[] args) {
GenericInterfaceImpl1 g = new GenericInterfaceImpl1();
g.method("字符串");
}
}
//定义接口
public interface GenericInterface<I> {
public abstract void method(I i);
}
//接口实现类
public class GenericInterfaceImpl2 implements GenericInterface<I> {
@Override
public void method(I i) {
System.out.println(i);
}
}
//使用实现类中的方法
public class Demo {
public static void main(String[] args) {
GenericInterfaceImpl2<String> g = new GenericInterfaceImpl2<>();
g.method("字符串");
}
}
泛型通配符
为什么要用通配符?
我在一个类中新建了两个集合,一个是ArrayLIst<Integer>类型的集合,一个是ArrayLIst<String>类型的集合。现在要实现定义一个方法遍历所有的ArrayList集合,这就用到了泛型通配符。
什么时候使用通配符?
当你不知道用什么类型来接受时,就可以使用泛型的通配符<?>,但是一旦使用泛型通配符后,只能使用Object对象来接收。
泛型通配符的使用
public static void printArray(ArrayList<?> list) {
Iterator<?> it = list.iterator();
while(it.hasNext()){
Object o = it.next();
System.out.println(o);
}
}
泛型的上下限
//泛型的上限:此时的泛型?必须是Number类型或者Number类型的子类
public static void getElement1(Collection<? extends Number> coll) {}
//泛型的下限:此时的泛型?必须是Number类型或者Number类型的父类
public static void getElement2(Collection<? super Number> coll) {}