泛型类
<>中的符号是代表属性类型
public class GenericTest<K,V,L> {
private K k;
private L l;
private V v;
public void setK(K k) {
this.k = k;
}
public void setL(L l) {
this.l = l;
}
public void setV(V v) {
this.v = v;
}
}
如果我们在使用的时候要限制K,L,V的类型,比如是某个类的子类、或者父类的话,就需要指定上下限。如下:
public static void main(String[] args) {
GenericTest<? super Number,? super ATest,? extends BTest> genericTest = new GenericTest<>();
}
? extends Number 为上限,? super ATest为下限。
如果要从集合中读取类型T的数据,并且不能写入,可以使用 ? extends 通配符;(Producer Extends)
如果要从集合中写入类型T的数据,并且不需要读取,可以使用 ? super 通配符;(Consumer Super)
泛型接口
与泛型类的定义方式类似。
public interface GenericInterface<T> {
T t();
}
泛型方法
定义
指的是返回值类型或者形参类型是T,<>中可以是多个泛型类型。
public static <T> T test(Class<T> t) throws IllegalAccessException, InstantiationException {
T t1 = t.newInstance();
return t1;
}
类型擦除
类型擦除是指编译阶段将替换为原始类型,这里有两种类型:
1、没有上下界,则将<>替换为Object;
2、如有有上下界,则替换为相应的上下界;
编译期类型检查
是指编译期间对引用调用的方法进行类型检查,可以从idea的错误信息得到印证:
Error:(22, 16) java: 对于add(int), 找不到合适的方法
方法 java.util.Collection.add(java.lang.String)不适用
(参数不匹配; int无法转换为java.lang.String)
方法 java.util.List.add(java.lang.String)不适用
(参数不匹配; int无法转换为java.lang.String)
由于类型擦除,调用
List list =new ArrayList<String>();
list.add("ew");
list.add(323);//编译通过
由于类型擦除,list原始类型是ArrayList,所以任何元素都可以。类型检查也是对应于boolean add(Object e);所以添加元素不会报错。正常编译。
如果是下面这样写:
List<String> list =new ArrayList<String>();
list.add("ew");
list.add(323);//编译错误
类型检查也是对应于boolean add(String e); 所以添加整形数值就会报错。
参考文章
https://itimetraveler.github.io/2016/12/27/%E3%80%90Java%E3%80%91%E6%B3%9B%E5%9E%8B%E4%B8%AD%20extends%20%E5%92%8C%20super%20%E7%9A%84%E5%8C%BA%E5%88%AB%EF%BC%9F/