泛型是一种特殊的类型,它把指定类型的工作推迟到客户端代码声明并实例化类或方法的时候进行。
为什么我们要在程序中使用泛型呢,JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题,所以我们一边为了减少不必要的错误,经常使用泛型。下面我们举例说明
ArrayList list = new ArrayList();
list.add("abc");
Integer num = (Integer) list.get(0); //运行时会出错,但编码时发现不了
list.add(new Random());
list.add(new ArrayList());
for(int i=0;i<list.size();i++){
(?)list.get(i); //此处取出来的对象应转换成什么类型
}
- 注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
- 泛形的基本术语,以ArrayList<E>为例:<>念着typeof
- ArrayList<E>中的E称为类型参数变量
- ArrayList<Integer>中的Integer称为实际类型参数
- 整个称为ArrayList<E>泛型类型
- 整个ArrayList<Integer>称为参数化的类型ParameterizedType
现在我们用泛型写几个实例应用
package cn.csdn.Generic;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
public class Demo01 {
@Test
public void test1(){
List<String> list =new ArrayList<String>();
list.add("abc");
list.add("123");
list.add("asf");
//for循环
for(String str:list) {
System.out.println(str);
}
//迭代
Iterator<String> ite=list.iterator();
while(ite.hasNext()){
String str=ite.next();
System.out.println(str+"这是用的迭代");
}
}
@Test
public void test2(){
Map<Integer,String> map =new HashMap<Integer,String>();
map.put(1,"zhangsan");
map.put(2,"lisi");
map.put(3,"wangwu");
Set<Map.Entry<Integer, String>> set=map.entrySet();
for(Map.Entry<Integer, String> ma:set){
System.out.println(ma.getKey()+" "+ma.getValue());
}
}
@Test
public void test3(){
Map<Integer,String> map =new HashMap<Integer,String>();
map.put(1,"zhangsan");
map.put(2,"lisi");
map.put(3,"wangwu");
Set<Integer> se =map.keySet();
Iterator<Integer> ite=se.iterator();
while(ite.hasNext()){
int k=ite.next();
System.out.println(k+" "+map.get(k)+"这是用的迭代");
}
for(Integer i:se){
System.out.println(i+" "+map.get(i)+"这是用的for循环");
}
}
}