戏说泛型

来源:互联网 发布:二手app软件排名 编辑:程序博客网 时间:2024/05/14 18:55


一.基本知识点。

/* 注意:

 * 1. 在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。

 * 2. 参数化类型不考虑类型参数的继承关系。

 *    即:  Vector <String> v =new Vector<Object>(); //错误

 *       Vector <Object> v = new Vector <String>(); // 也错误

 *    

 *     但是  Vector v1= newVector<String>(); 正确。

 *         Vector<Object> v = v1;    正确。因为此时编译器认为是原始类型的v1 给参数化类型的v。

 * 基础知识见包: com.hu.Collection  中的GenericDemo系列

 *  3 通配符:也为占位符

 * 泛型限定:

 *    ?extends  E :可以接收E类型 或者E的子类型。 其中E为上限。

 *    Vector <? extends Number> v1 = new Vector<Integer>(); 正确,Integer 继承了Number

 *    Vector <? extends Number> v2 = new Vector<String>();

 *    ?super   E :可以接收E 类型或者 E的父类型。其中E下限。

 *    Vector <? super Integer>  v3= new Vector<Number>();

 *     Vector <? super Integer>  v4 = new Vector<Byte>();

 *  4.如果一个类的多个方法,操作同一个对象,需要使用泛型时,就把泛型定义在类上面。

 */

二.程序演示, 对HashMap进行迭代,取出其中的key 和value。

importjava.util.*;

publicclass GenericHash {

   

     public static void main(String[] args)

     {

              HashMap<String ,Integer>  maps = new HashMap<String, Integer>();

         maps.put("zxx",28);

         maps.put("flx",33);

        

         Set<Map.Entry<String,Integer>>  entrySet =maps.entrySet();

         for (Map.Entry<String ,Integer>entry: entrySet)

         {

       //Map.Entry<K,V>是映射项(键-值对)获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。

        //      这些 Map.Entry 对象仅 在迭代期间有效;  

        

                  System.out.println(entry.getKey()+":"+entry.getValue());

         }

         //以上迭代

     }

}

三.通过字节码文件,来获取泛型类型。

由于编译器的去类型化(即编译完后,对于Vector<Date>和Vector <Integer> 其对应的字节码是同一份)也就是通过Vector<Date>.class或者Vector<Integer>.class  无法获取到自己本身的泛型类型。

但是我们还想知道 Vector<Date> 的一个对象的泛型类型,Hibernate就有这样的应用。

 因此说  泛型 是给编译器看的。运行的时候已经没有泛型的约束了。

 解决方法:1.定义一个方法,而参数是该泛型的一个对象。

         2.我们知道能够通过反射获取一个方法的参数列表,只要以泛型的方式

         Type[] types=appmethod.getGenericParameterType() 获取参数。

         3. 将得到的types[i]一个参数强制转换成参数化类型ParameterizedType即可。

 

importjava.lang.reflect.Method;

importjava.lang.reflect.ParameterizedType;

importjava.lang.reflect.Type;

importjava.util.*;

publicclass GenericRefl <T>{

        

         public static voidappSet(Set<Date> d)

         {

                  

         }

         public static void main(String[] args)throws Exception

         {

                   // Set <Date> d = newSet <Date>();

                   Method appMethod =GenericRefl.class.getMethod("appSet", Set.class);// 1

                   Type[]  types=appMethod.getGenericParameterTypes(); //2 getGenericParameterTypes()

        //按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的。

                   ParameterizedType   ptype = (ParameterizedType)types[0];//3 我们知道第一个参数是<Date>泛型类型

                  

                   System.out.println(ptype);

                   System.out.println(ptype.getRawType());

                   System.out.println(ptype.getActualTypeArguments()[0]);//实际类型参数获得是一个数组,返回[0]元素,因为HashMap<K,V>有两个实际类型。

                  

         }

 

}



原创粉丝点击