泛型
(1)增强了java的类型安全,可以在编译期间对容器内的对象进行类型检查,在运行期不必进行类型的转换。
而在java se5.0之前必须在运行期动态进行容器内对象的检查及转换,泛型是编译时概念,运行时没有泛型
减少含糊的容器,可以定义什么类型的数据放入容器
(2)List<Integer> aList = new ArrayList<Integer>();
aList.add(new Integer(1));
// ...
Integer myInteger = aList.get(0); //从集合中得到的元素也不必强制类型转换 也是好处之一吧
支持泛型的集合,只能存放制定的类型,或者是指定类型的子类型。
HashMap<String,Float> hm = new HashMap<String,Float>();
不能使用原始类型
GenList<int> nList = new GenList<int>(); //编译错误
编译类型的泛型和运行时类型的泛型一定要一致。没有多态。
List<Dog> as = new ArrayList<Dog>();
List<Animal> l = as; //error Animal与Dog的父子关系不能推导出List<Animal> 与 List<Dog> 之间的父子类关系
(3)泛型的通配符"?"
? 是可以用任意类型替代。
<?> 泛型通配符表示任意类型
<? extends 类型> 表示这个类型是某个类型或接口的子类型。
注意:当这种通配符修饰集合时,集合对象只能访问,不能修改,可以删除
<? super 类型> 表示这个类型是某个类型的父类型。
List<? super String> 表示是String类的父类,不包括String类本身
import java.util.*;
import static java.lang.System.*;
public class TestTemplate {
public static void main(String[] args) {
List<Object> l1=new ArrayList<Object>();
List<String> l2=new ArrayList<String>();
List<Number> l3=new ArrayList<Number>(); //Number --- Object的子类,所有封装类的父类
List<Integer> l4=new ArrayList<Integer>();
List<Double> l5=new ArrayList<Double>();
print(l1);
print(l2);
print(l3);
print(l4);
print(l5);
}
static void print(List<? extends Number> l){ //所有Number及其子类 l3,l4,l5通过
for(Number o:l){
out.println(o);
}
}
static void print(List<? extends Comparable> l){……} //任何一个实现Comparable接口的类 l2,l4,l5通过
static void print(List<? super Number> l){……} //所有Number及其父类 l1,l3通过
// "?"可以用来代替任何类型, 例如使用通配符来实现print方法。
public static void print(GenList<?> list){……} //表示任何一种泛型
}
(4)泛型方法的定义 --- 相当于方法的模版
把数组拷贝到集合时,数组的类型一定要和集合的泛型相同。
<...>定义泛型,其中的"..."一般用大写字母来代替,也就是泛型的命名,其实,在运行时会根据实际类型替换掉那个泛型。
在方法的修饰符和返回值之间定义泛型
<E> void copyArrayToList(E[] os,List<E> lst){……}
static <E extends Number & Comparable> void copyArrayToList(E[] os,List<E> lst){……} //定义泛型的范围 类在前接口在后
static<E , V extends E> void copyArrayToList(E[] os,List<E> lst){……} //定义多个泛型
"super"只能用在泛型的通配符上,不能用在泛型的定义上
import java.util.*;
public class TestGenerics3 {
public static void main(String[] args) {
List<String> l1=new ArrayList<String>();
List<Number> l2=new ArrayList<Number>();
List<Integer> l3=new ArrayList<Integer>();
List<Double> l4=new ArrayList<Double>();
List<Object> l5=new ArrayList<Object>();
String[] s1=new String[10];
Number[] s2=new Number[10];
Integer[] s3=new Integer[10];
Double[] s4=new Double[10];
Object[] s5=new Object[10];
copyFromArray(l1,s1);
copyFromArray(l2,s2);
copyFromArray(l3,s3);
copyFromArray(l4,s4);
copyFromArray(l5,s5);
}
//把数组的数据导入到集合中
public static <T extends Number&Comparable> void copyFromArray(List<T> l,T[] os){
for(T o:os){
l.add(o);
}
}
}
受限泛型是指类型参数的取值范围是受到限制的. extends关键字不仅仅可以用来声明类的继承关系, 也可以用来声明类型参数(type parameter)的受限关系.
泛型定义的时候,只能使用extends不能使用 super,只能向下,不能向上。
调用时用<?>定义时用 <E>
(5)泛型类的定义
类的静态属性和静态方法不能使用泛型,因为泛型类是在创建对象的时候产生的。
class MyClass<E>{
public void show(E a){
System.out.println(a);
}
public E get(){
return null;
}
}
受限泛型
class MyClass <E extends Number>{
public void show(E a){
}
}