------------------------------------------------------------
泛型入门
1 jdk1.5以前的集合中存在的问题
ArrayList collection=new ArrayList();
collection.add(1);
collection.add(1L);
collection.add("abc");
int i=(Integer)arrayList.get(1);//编译要强制类型转换且运行时出错!
2 jdk1.5的集合类希望你在定义集合时,明确表示你要向集合中装那种类型
的数据,无法加入指定类型以外的数据
ArrayList<Integer> collection2=new ArrayList<Integer>();
3 泛型是提供javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源
程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息
,使程序的运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回
值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过
编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再用
其add方法即可。
--------------------------------------------------------------------------------------
了解泛型
1.ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:
》整个称为ArrayList<E>泛型类型
》ArrayList<E>中的E称为类型变量或参数
》整个ArrayList<Integer>称为参数化的类型
》ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
<>念着typeof;
》ArrayList称为原始元素
2 参数化类型与原始类型的兼容性:
》参数化类型可以引用一个原始类型的对象,编译报告警告,例如
Collection<String> c=new Vector();//(new Vector可以看做是1.4中的而泛型是在jdk1.5才有,而新参数化类型要兼容老的,所以可以通过编译
》原始类型可以引用一个参数化类型的对象,编译报告警告,例如,
Collection c=new Vector<String>();//原来的方法接受一个集合参数,新的类型也能传进去
3 参数化类型不考虑类型参数的继承关系:
》Vector<String> v=new Vector<Object>();//错误!不写<Object>没错,写了就是名知故犯
》Vector<Object> v=new Vector<String>();//也错误
4 在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:
Vector<Integer> vectorList[]=new Vector<Integer>[10];
思考题:下面的代码会报错误吗?
Vector v1=new Vector<String>();
Vector<Object> v=v1;
答:编译器编译代码是一行一行的编译当编译Vector v1=new Vector<String>();
时发现参数化的类型给原始类型可以,当编译:Vector<Object> v=v1;时发现原始
类型给参数化的类型也可以(一定要明白编译阶段和运行阶段)
-----------------------------------------------------------------------------------------
如果使用泛型,体验泛型:
public class GenericTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
ArrayList collection1=new ArrayList();//这是未使用泛型事集合中可以放置任何类型的数据。
collection1.add(1);
collection1.add(1.0);
collection1.add("abc");
//int i=(Integer)collection1.get(1);//如果释放这句代码编译器会报错,因为1.0不能转换为整型,这里可以看出不使用泛型带来的弊端
//泛型入门
ArrayList<String> collection2=new ArrayList<String>();
//collection2.add(1);
//collection2.add(1.0);
//collection2.add("abc");
//String element=collection2.get(0);
/*使用泛型Constructor<String>后constructor.newInstance(new String("lhm"));
* 得到的一定是一个String类型,所以不必进行强制类型转换
* *
*/
Constructor<String> constructor=String.class.getConstructor(String.class);
String string=constructor.newInstance(new String("lhm"));
System.out.println(string);
ArrayList<Integer> collection3=new ArrayList<Integer>();
//我们可以看到结果为true,表示编译器编译过程中会把泛型的类型去掉,这样得到的是同一份字节码
System.out.println(collection2.getClass()==collection3.getClass());
//collection3.add("abc");
//用反射跳过编译器,把不同的类型放入collection中(也就是泛型只是给编译器看到)
collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");
System.out.println(collection3.get(0));
collection2.getClass().getMethod("add",Object.class).invoke(collection2, 2);
System.out.println(collection2.get(0));
}
}
学到了这里由此可以总结jdk1.5的新特性有:枚举,泛型了。。。