黑马程序员——泛型的用法

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ---------------------

什么是泛型:

泛型是提供给javac编译器使用的,可以限定集合的输入类型,让编译器阻止源程序中的非法输入,编译器编译带类型的集合输入时会去掉带类型信息,是程序的运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样,由于编译器生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型几个中加入其他类型的数据,如:反射得到的集合,再调用add方法即可。


泛型中的术语:
整个ArrayList<E>为泛型类型
ArrayList<E>中的E称为类型变量和类型参数
ArrayList<Integer>称为参数化的类型
ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
ArrayList<Integer>中的<>念typeof
ArrayList<>为原始类型

代码展示:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.  /*没有用泛型*/  
  2.       ArrayList collection1=new ArrayList();  
  3.       collection1.add(1);  
  4.       collection1.add(1L);  
  5.       collection1.add("abc");  
  6.       //int i=(Integer)collection1.get(1);  
  7.       /*泛型修改上面代码*/  
  8.       ArrayList<String> collection2=new ArrayList<String>();  
  9. //      collection2.add(1);  
  10. //      collection2.add(1L);  
  11.       collection2.add("abc");  
  12.       String element=collection2.get(0);  
  13.         
  14.       /*在反射中应用泛型*/  
  15.       //String str2=(String)constructor1.newInstance("abc");  
  16.       Constructor<String> constructor1=String.class.getConstructor(StringBuffer.class);  
  17.         String str2=constructor1.newInstance(new StringBuffer("abc"));//必须进行转换  
  18.         /* 
  19.          * Class.newInstance()方法 
  20.          * 该方法内部先得到默认的构造方法,在用得到的构造方法去创建实例对象 
  21.          */  
  22.         /*String obj=(String)Class.forName("abc").newInstance();*/  
  23.         System.out.println(str2.charAt(2)); //输出c  
  24.           
  25.         ArrayList<Integer> collection3=new ArrayList<Integer>();  
  26.         System.out.println(collection3.getClass()==collection2.getClass());//true  
  27.         //collection3.add("abc");  
  28.         //透过编译器进行反射,JDK的特性,自动装箱功能  
  29.         collection3.getClass().getMethod("add", Object.class).invoke(collection3, "abc");  
  30.         System.out.println(collection3.get(0));//打印abc  

泛型集合的综合实例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.              /*泛型集合的实例*/  
  2. HashMap<String, Integer> maps=new HashMap<String, Integer>();  
  3. maps.put("jzy"20);  
  4. maps.put("heima"32);  
  5. maps.put("cast"30);  
  6. Set<Map.Entry<String, Integer>> entrySet=maps.entrySet();  
  7. for(Map.Entry<String, Integer> entry:entrySet)  
  8. {  
  9.     System.out.println(entry.getKey()+":"+entry.getValue());  
  10. }  


自定义泛型:

public static <T> T add(T x,T y){return null;}

调用自定义的泛型:
  add(3,5);
  Number x2=add(3.25,6);--->这个是Number类型的
  Object obj=add("abc",26);---->这个是Object类型


完成类型的交换:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private static <T> void swap(T[] a,int i,int j){//T必须是引用类型  
  2.   T tmp=a[i];  
  3.   a[i]=a[j];  
  4.   a[j]=tmp;  
  5.  }  

调用类型交换:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. swap(new String[] {"abc","xyz","itcast"},1,2);//传入三个字符串,并对第一个和第二个进行交换  
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //swap(new int[] {1,2,3,4,5,5},3,4); //int[]  是一个数组对象,不能使用  


注意:
1.在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。
2.当一个变量被声明为泛型时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态变量和静态方法调用。
因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。



泛型练习:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /*采用自定义类型方法的方式打印任意参数化类型中的所有内容*/  
  2.     public static <T> void printCollection2(Collection<T> collection)  
  3.     {  
  4.         System.out.println(collection.size());  
  5.         for(Object obj:collection)  
  6.         {  
  7.             System.out.println(obj);  
  8.         }  
  9.     }  
  10. /*定义一个方法,该方法打印任意参数类型的集合中的所有数据,需要用到通配符*/  
  11.     public static void printCollection(Collection<?> collection)  
  12.     {  
  13.         //collection.add("abc");//这句话会报错。。  
  14.         collection=new HashSet<Date>();//这句可以  
  15.         System.out.println(collection.size());  
  16.         for(Object obj:collection)  
  17.         {  
  18.             System.out.println(obj);  
  19.         }  
  20.        }  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /*定义一个方法,将任意类型的数组中的元素填充为某个相应的对象*/  
  2.     private static <T> void fillArray(T[] a,T obj){  
  3.         for(int i=0;i<a.length;i++){  
  4.             a[i]=obj;  
  5.         }  
  6.     }  
  7.     /*编写一个泛型方法,自动将Object类型转换为其他类型*/  
  8.     private static <T> T autoConvert(Object obj){  
  9.         return (T)obj;  
  10.     }  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.              /*通过反射获得实际类型的参数*/  
  2. //Vector<Date> v1=new Vector<Date>();  
  3. Method applyMethod=GenericTest.class.getMethod("applyVector", Vector.class);  
  4. Type[] types=applyMethod.getGenericParameterTypes();  
  5. //参数化类型  
  6. ParameterizedType ptype=(ParameterizedType)types[0];  
  7. System.out.println(ptype.getRawType());//得到原始的类型  
  8. System.out.println(ptype.getActualTypeArguments()[0]);//得到实际类型参数

--------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值