泛型
一、泛型的概念
泛型顾名思义就是广泛、宽泛的类型。类、接口和方法都能使用泛型来约束,代码和操作类型不在严格绑定,泛型可以提高代码的复用,降低耦合性,提升安全性等优点。
二、泛型的原理
java源码是需要先经过编译器编译成class文件,才会被虚拟机识别得以运行的,在编译阶段会通过泛型擦除将泛型类,转换成普通的非泛型代码,将类型T转成Object,并插入强制类型转换。
java
Show<String> show = new Show<>("123");
String t = show.getT();
三、泛型应用于类
java
public class Show <T,U> {
private T t;
private U u;
public Show(T t, U u) {
this.t = t;
this.u = u;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public U getU() {
return u;
}
public void setU(U u) {
this.u = u;
}
}
四、泛型用于接口
java
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
五、泛型用于方法
泛型既能用于类和接口,也能用于方法,即使类不是泛型类,方法也是使用泛型的,之间并没有关系。
java
public static <T> void showTime(T t){
System.out.println(t);
}
六、泛型参数的限定
extends 关键字表示java给定泛型参数一个上界,参数只能是这个上界的子类或者上界本身。
java
public static <T extends Number> List andT(T[] t){
List<T> list = new ArrayList<>();
Arrays.stream(t).forEach(v -> list.add(v));
return list;
}
public static <T extends Comparable> List andT(T[] t){
List<T> list = new ArrayList<>();
Arrays.stream(t).forEach(v -> list.add(v));
return list;
}
如上所示,T不是具体代指某一类,而是Number以及Number的子类。
super关键字表示表示给定泛型参数的一个下界,参数只能是这个下界或者下界的超类。
java
class F implements Comparable<F>{
private Integer aa;
public F(Integer aa) {
this.aa = aa;
}
@Override
public int compareTo(F o) {
return 0;
}
}
class C extends F{
public C(Integer aa) {
super(aa);
}
}
// 下界通配符能够保证接受C以及C的超类
public void tt(List<? super C> list){
System.out.println(list);
}
总结:
- 上界通配符,便于读取,因为读取的类型是T或者T的子类,可以通过强制类型转换成具体的子类,来进行处理。
- 下界通配符,便于写入,不能读取,因为写入只需要是T或者T的超类即可,读取的因为不知道具体的超类,无法进行转换。