泛型

1.入门泛型的基本应用

 在java1.5 之前,我们在使用集合框架的时候,返回值都是Object 对象;当我们取出来的时候需要类型转换;效率不高;从java1.5之后,引出了泛型,就不需要类型装换了。
这时集合里只能存在同一个对象,这样存贮和使用更加的安全。

2.泛型的内部原理及更深应用

 泛型:是用于告诉编译器,明确的表示集合只装哪一种变量。编译完成之后已经去掉了类型信息,意思就是说他们在内存中都是同一份字节码的;以下代码返回true 说明了这个问题。
Collection<Integer>collection1 =new ArrayList<Integer>();
      Collection collection2 = newArrayList();
      System.out.println(collection1.getClass() ==collection2.getClass());

在编译期间去掉类型,我们叫做去类型化;
在这个时候, 我们有一些哥们就想了,去类型化是在编译间进行的,他们在内存里是同一个字节码,我们可以通过反射穿透泛型,通俗一点就是通过反射向数据里面加入不同类型的值。
代码: 向Integer 泛型集合中添加了一个字符串

packageorg.nagi.annotation;
importjava.util.ArrayList;
importjava.util.List;

publicclass TestCollection {
   publicstaticvoid main(String[] args)throws Exception {

      List<Integer> list1 = new ArrayList<Integer>();
      List list2 = newArrayList();

      list1.getClass().getMethod("add",  Object.class).invoke(list1,"abcd");

      System.out.println(list1.get(0));
   }
}

运行结果:abcd
结果说明了:泛型只是给编译器看的。

**3.泛型的通配符扩展应用
泛型的通配符<?> 数据类型,类不能够继承。

List<? Extens Number> = new ArrayList<Integer>();正确

限定通配符的下边界

List<? super Integer> = new ArrayList<Number>(); 正确

4.泛型集合的综合应用案例

 例子:迭代遍历一个泛型Map

代码:

packageorg.nagi.annotation;
importjava.util.HashMap;
importjava.util.Map;
importjava.util.Map.Entry;
importjava.util.Set;
publicclass TestCollection {
   publicstaticvoid main(String[] args)throws Exception {
      Map<String,Integer> m = new HashMap<String, Integer>();
      m.put("high", 175);
      m.put("weight", 75);
      m.put("age", 23);
      //得到Map的entrySet集合
      Set<Map.Entry<String,Integer>>  entrySet = m.entrySet();
      //循环迭代
      for(Entry e : entrySet){
        System.out.println(e.getKey() +":"+e.getValue());
      }
   }
}

运行的结果:
weight:75
age:23
high:175

5.自定义泛型方法及其应用
Java 的泛型是从C++泛型继承过来的,泛型的实现基本上是编译期。
通配符类型定义

   privatestatic <T> Tadd(Tx,T y){
      returnnull;
   }

6.自定义泛型方法的练习与类型推断总结

   1、泛型转换:Object自动转换为任意类型
    private static <T> TautoConvert(Object obj){
      return(T)obj;
   }

2、定义一个泛型,可以将任意数组中填充为任意对象

    private static <T>voidfillArray(T[] a,T obj){
      for(int i=0;i<a.length;i++){
        a[i] = obj;
      }
  }

3、打印任意类型的集合,

public static <T> void printCollection2(Collection<T> collection){
      System.out.println(collection.size());
      for(Object obj : collection){
        System.out.println(obj);
      }
  }

4、把任意类型的数组复制集合到数组

public static <T>void copy1(Collection<T> dest,T[] src){
   }

7.自定义泛型类的应用

 在Dao 泛型的使用,在Dao层常常使用到CUID 操作, 对于不同对象有不同的CUID,这时我们考虑使用泛型来降低Dao层的代码量。这时在Dao层使用的是类级别的泛型。
importjava.util.Set;

//daodata access object--->crud
publicclass GenericDao<E> {
   //save
   publicvoid add(E x){

   }

   //查询
   public E findById(int id){
      returnnull;
   }
   //删除
   publicvoid delete(E obj){

   }
   //通过ID删除
   publicvoid delete(int id){

   } 
   //更新
   publicvoid update(E obj){

   }
   //通过姓名查询
   public E findByUserName(String name){
      returnnull;
   }
   //集合查询
   public Set<E> findByConditions(String where){
      returnnull;
   }
}

8.通过反射获得泛型的实际类型参数

前面我们都知道可以通过泛型向集合中存入指点的数据,但是我们如果从数据库里面取出数据的时候,什么让它直接返回之前定义的泛型类型呢???

Hibernate 底层是可以做到这一点的;
hibernate 在从数据库里面取出数据的时候,它不是直接的通过集合方法得到的的,而是通过定义一个方法来得到的。因为Method的反射方法里面有

getGenericParameterTypes()方法,可以得到参数泛型对象。
Type[]
getGenericExceptionTypes()
  返回 Type 对象数组,这些对象描述了声明由此 Method 对象抛出的异常。
Type[]
getGenericParameterTypes()
  按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的。
Type
getGenericReturnType()
  返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象。
例子代码:
//通过Method
   publicstaticvoid applyVector(Vector<Date> v1){
      //从数据库里Load出数据
   }

MethodapplyMethod = GenericTest.class.getMethod("applyVector", Vector.class);
      Type[] types =applyMethod.getGenericParameterTypes();
      ParameterizedType pType =(ParameterizedType)types[0];
      System.out.println(pType.getRawType());//原始的类型
      System.out.println(pType.getActualTypeArguments()[0]);//实际参数类型
   }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值