1. 泛型思想
泛型是JDK1.5后出现的一个安全机制.通过< >来指定容器中元素的类型
JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:
ArrayList list = newArrayList();
list.add("abc");
Integer num = (Integer)list.get(0); //运行时会出错(String不能强转为Integer),但编码时发现不了
list.add(new Random());
list.add(new ArrayList());
for(inti=0;i<list.size();i++){
(?)list.get(i); //此处取出来的对象应转换成什么类型,这时编写的时候程序员不能确认
}
2.泛型好处:
1.将运行时期出现的问题转移到编译时期。
2.避免了强制类型转换的麻烦
JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
l 泛形的基本术语,以ArrayList<E>为例:<>念着typeof
• ArrayList<E>中的E称为类型参数变量
• ArrayList<Integer>中的Integer称为实际类型参数
• 整个称为ArrayList<E>泛型类型
• 整个ArrayList<Integer>称为参数化的类型ParameterizedType
3. 泛型典型应用
例子一:使用迭代器迭代泛形集合中的元素。
例子二:使用增强for循环迭代泛形集合中的元素
例子三:存取HashMap中的元素
packagecom.java.Demo;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.Set;
importorg.junit.Test;
publicclass Demo2 {
@Test
publicvoid test1() {
Map<Integer,String> m = new HashMap<Integer, String>();
m.put(1,"a");
m.put(2,"b");
m.put(3,"c");
m.put(4,"d");
Set<Map.Entry<Integer,String>>set = m.entrySet();
for(Map.Entry<Integer,String> me : set) {
System.out.println(me.getKey()+"......."+me.getValue());
}
}
}
4.使用泛形时的几个常见问题:
使用泛形时,泛形类型须为引用类型,不能是基本数据类型
使用泛型两边的类型必须一致
• ArrayList<String> list= new ArrayList<Object>(); //错
• ArrayList<Object> list= new ArrayList<String>(); //错
• ArrayList<String> list= new ArrayList<String>(); //行
两边只有一边用泛型也可以(为了保持兼容性),Java语言中的泛型是维护向后兼容的,即我们完全可以不采用泛型,而继续沿用过去的做法
• ArrayList<String> list= new ArrayList (); //行
• ArrayList list = newArrayList<String>(); //行
在高版本开发环境中编译未启用泛型机制的集合类应用代码时,会输出编译提示信息
静态方法不可以使用类中定义的泛型。因为类中的泛型需要在对象初始化的时,指定具体类型。而静态优先与对象存在。静态方法上定义泛型,一定要写在static关键字的后面。返回值类型的前边
泛型方法使得该方法能够独立于类而产生变化。以下是一个基本指导原则:
无论何时,只要能做到,就应该尽量使用泛型方法;也就是说,如果使用泛型方法可以取代这个类泛型化,那么就应该只使用泛型方法,因为它可以事情更清楚明白。