------------------------------------------------------------

                           泛型入门

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的新特性有:枚举,泛型了。。。