泛型的根本应用、内部原理及更深应用
泛型的基本应用、内部原理及更深应用
1. jdk1.5以前的集合类中存在什么问题
a) ArrayLIst collection = new ArrayList();
collectin.add(1);
collection.add(1L);
collection.add(“abc”);
int I = (Integer)ArrayList.get(1); //编译器强制类型转换且运行时出错
2. jdk1.5的集合类希望你在定义集合时,明确规定表示你要向集合中装哪种类型的数据,无法加入指定类型以外的数据;
a) ArrayList<Integer> collection2 = new ArrayList<Integer>();
collection2.add(1);
collection2.add(1L); //error
collection2.add(“abc”); //error
int i2 = collection2.get(0); //利用泛型号,不需要强制转换了
3. 泛型号是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉类型信息,使程序运行效率不受影响,对于参数化的类型,getClass()方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用拟向得到集合,再调用其add方法即可。
4. ArrarList<E> 类定义和ArrayList>Integer>类引用中涉及如下术语言:
b) 整个称为ArrayList<E>泛型类型
c) ArrayList<E>中的E称为类型变量或类型参数
d) ArrayList<Integer>称为参数化类型
e) ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
f) ArrayList<Integer>中的<>念typeof
g) ArrayList称为原始类型
5. 参数化类型与原始类型的兼容性:
h) 参数化类型可以引用一个原始类型的对象,编译器给予警告,例如:
Collection<String> c = new Vector();
i) 原始类型可以引用一个参数化的类型对象,编译器给予警告,例如
Collection = new Vector<String>(); //原来的方法接受一个集合参数,新的类型也要能传进去。
6. 参数化类型不考虑类型参数的继承关系:
j) Vector<String> v = new Vector<object>();//error
k) Vector<Object> v = new Vector<String>(); //error to
7.在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面的语句有错误:
Vector<Integer> vectorList[] = new Vector<Integer>[10];
8.下面的代码会报错吗? 一看会,实际却不会,编译器是一行一行检查的
Vector v1 = new Vector<String>(); Vector<Object> v = v1;
泛型的通配符扩展应用
A. 限定通配符的上边界://上边界为Number
a) 正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
B. 限定通配符的下边界 // 下边界为Integer
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
综合实例代码: