泛型是jdk1.5的新特性,是提供给Javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入
例子: ArrayList collection1 = new ArrayList();
collection1.add(12);
collection1.add("adssa");
集合collection1在不使用泛型的情况下,可以任意添加各种类型的数据,在取数据时不能确定是何种类型,需进行强制类型转换,容易出错,如果使用泛型则可以将输入限定输入类型为某一种,取数据时可以免去强制类型转换,避免因类型转换带来的错误
泛型的使用: ArrayList<String> collection2 = new ArrayList<String>();
collection2.add(12); //非法,输入类型已被限定为String
collection2.add("adssa");
泛型在反射中的应用: Constructor<String> constructor = String.class.getConstructor(StringBuffer.class);
String str = constructor.newInstance(new StringBuffer("abc"));//不需进行强制类型转换
泛型只在编译时起作用,编译器在编译带类型说明的集合时会去除掉类型信息,只要跳过编译器,就可以往集合中添加其他类型的数据,例如: ArrayList<String> collection = new ArrayList<String>();
collection.add("aas");
System.out.println(collection.get(0));
// collection.getClass().getMethod("add",Object.class).invoke(collection,12);
ArrayList.class.getMethod("add",Object.class).invoke(collection, 12);
System.out.println(collection.get(1));
利用反射透过编译器,往集合中添加数据。
泛型术语:ArrayList<E>类定义与ArrayList<Integer>类定义
整个ArrayList<E>称为泛型类型
ArrayList<E>中的E称为类型变量或类型参数
ArrayList<Integer>称为参数化的类型
ArrayList<Integer> 中的 Integer 称为类型参数的实例 或 实际类型参数
ArrayList<Integer> 中的 <> 念成type of
ArrayList 称为 原始类型
参数化类型与原始类型的兼容性:
参数类型可以引用一个原始类型的对象,编译报警
Collection<String> c = new Vector();
原始类型可以引用一个参数化类型对象,编译报警
Collection c = new Vector<String>();
参数化类型不考虑类型从参数的继承关系:
Vector<String> V = new Vector<Object>();编译报错
在创建数组实例时,数组的元素不能使用参数化类型。
泛型通配符
public void printCollection(Collection<?> collec){
System.out.println(collec.size());
// collec.add("wew"); //非法,并不是每一种类型都支持add(),与参数化有关
for(Object obj:collec)
{
System.out.println(obj);
}
}
在上述代码中出现的”?“就是泛型通配符,使用通配符可以引用其他各种参数化类型,可以调用与参数化无关的方法,不能调用与参数化有关的方法
Vector<? extends Number> x = new Vector<Integer>;其中的extends Number指定通配符的上边界,只能为其本身和其子类 ;Vector<? super Integer> x = new Vector<Number>;指定下边界
泛型综合应用案例
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("abc",1);
map.put("ab2",2);
map.put("a1",3);
Set<Map.Entry<String,Integer>> setEntry = map.entrySet();
for(Map.Entry<String,Integer> entry:setEntry)
{
System.out.println(entry.getKey()+entry.getValue());
}