泛型是jdk1.5里出现的一个非常重要的功能,之前一直只是会使用一点泛型,但是对泛型一些复杂的使用形式总是把握不准,端午节闲来无事,就研究了一下泛型,现做一下总结:
泛型的出现是为了解决类型定义出现的,它使得类型的创建更加灵活。
创建固定的类型
示例:
class Pair<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
这种形式是定义固定的类型,那么我们使用个的时候必须得传入一个固定的类型
通配符类型
通配符是采用?来表示的,它用来表示一种不确定的类型,主要形式有 ?extends T,表示继承自T的一种类型;另外一种是? super T,表示T的父类,两种类型各有不同的用途:
? extends T 表示最大是T类型,可以用来遍历继承自T类型的集合,但是不能用来表示集合添加的方法,只能能添加null类型,因为我们表示的是T的子类,那么各个子类可定是不相同的,并且是区别的,所以添加的时候肯定是有问题的。小提示:如果一个list既可以添加Integer类型又能添加String类型,那么去取的时候我们怎么判断每个元素的类型呢?
大家可以参考这段代码去思考
public class Test {
public static void fillNumberList(List<? extends Number> list) {
list.add(new Integer(0));//编译错误
list.add(new Float(1.0));//编译错误
}
public static void main(String[] args) {
List<? extends Number> list=new ArrayList();
list.add(new Integer(1));//编译错误
list.add(new Float(1.0));//编译错误
}
}
?super T表示是T类型的父类,如果我们想要添加T的子类肯定是可以的。因为表示的类型足够大。
那么这段类型是肯定不会有问题的
public class Test {
public static void fillNumberList(List<? super Number> list) {
list.add(new Integer(0));
list.add(new Float(1.0));
}
public static void main(String[] args) {
List<? extends Number> list=new ArrayList();
list.add(new Integer(1));
list.add(new Float(1.0));
}
}
```
######泛型擦除
泛型擦除是指,我们定义的泛型在jvm实际是不存我们的泛型的。它只在编译时进行检查,而在实际编辑完成的时候不会存储泛型类型的,这也就是为什么下面的代码的输出结果是true的原因
```
public class GenericType {
public static void main(String[] args) {
ArrayList<String> arrayString=new ArrayList<String>();
ArrayList<Integer> arrayInteger=new ArrayList<Integer>();
System.out.println(arrayString.getClass()==arrayInteger.getClass());
}
}
```