Java中的泛型

Java中的泛型jdk1.5之后的一个重要的特性。
泛型:英文Generic
1.定义:泛型是 程序设计语言的一种特性。允许程序员在 强类型 程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种 程序设计语言和其 编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种 数据类型泛型类引用类型,是 堆对象,主要是引入了类型参数这个概念
2.使用jak中的泛型
    (1) 声明一个ArrayList的容器对象可以使用泛型,用法是在类名后面加一对尖括号来指定具体的类型化参数
      ArrayList<String> arrl=   new  ArrayList<String>();
//这样就指明了在这个ArrayList的容器中只能装类型类型为String的对象
      arrl.add( "sjkfh" );
   arrl.add( 9 );//这里编译器就会报错,因为声明的参数化类型是String类型的对象,不能add整数类型的对象
     (2)泛型中的?通配符。使用?通配符就表明了这个泛型可以接受任何类型的参数,例如写一个方法它可以接受任何类型的参数,可以这样定义:

//体验泛型的?通配符,在泛型的尖括号中用问号来指定就不确定具体的类型是什么了,就可以统配任何类型了
      //使用?通配符可以使用其他任何参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不可以调用与参数化有关的方法
      public   static   void   printColletion(Collection<?> collection){
         System.   out  .println(collection.size());
            for  (Object obj:collection){
             System.   out  .print(obj);
         }
    }
    (3 )?通配符的扩展:
            限定通配符的上边界,如:
                Vector<?  extends  Number> v1=   new  Vector<Number>();
               这里是声明了Vector的对象的泛型,它参数化类型是任意的,但限定了范围,这里表明了它的参数化类型只能是Number以及继承了Number的之类的类型
           限定通配符的下边界,如:
                Vector<?  super  Integer> v2=   new  Vector<Number>();
               同样的这里也定义了泛型的参数化类型,它的范围只能是Integer以及它的父类
3.自定义泛型。
(1)定义泛型的方法,要定义一个方法使它能作用于任何类型的参数可以这样写,在方法的返回值前面加上尖括号<E>如有返回值则应在泛型的后面指定同样的类型E
//定义一个方法 对传入的Object类型的对象转换成其他类型的对象
      private   static  <T> T autoConvert(Object obj){
            return  (T)obj;
    }
//定义一个方法,能打印出任意类型集合中的所有元素
      public   static  <T>  void  printColletion1(Collection<T> collection){
         System.   out  .println(collection.size());
            for  (Object obj:collection){
             System.   out  .print(obj);
         }
    }
(2)定义泛型类,定义泛型类只需要在类名的后面加上尖括号<E>可以了
public   class  GenicDao<E>
需要注意的是:在类中定义的方法的类型必须严格按照类的泛型来定义,同时还不能有static方法,因为在泛型类中 因为在泛型中只能指定了对象, 而静态的方法直接用类名来调用则会混淆。 如果你硬要定义静态方法则要在你定义的泛型方法中自定义泛型
public   static   <E>  void  updeta2(E e){
         
}
注意这里的E和类中的E是两个不同的概念哈!

4.在java中的泛型它只是给编译器看,在编译器编译变成字节码后,它的具体的参数化类型就没有区别了可以做这样的一个测试
ArrayList<String> arrl=   new  ArrayList<String>();
ArrayList<Integer> arr2=   new  ArrayList<Integer>();
System.  out .println(arrl.getClass() == arr2.getClass()); //output:true
从输出的结果为true可以看到这两份字节码是一样的,所以证明了泛型只是给编译器看,而编译过后则丢失了指定引用类型的区分。
另外一个泛型中的重要知识点:我们可以通过反射来透过编译器来获取泛型中的实际参数类型。 首先说明一下,我们想通过获得类的字节码来区分一个集合里到底装的是什么类型,这样是行不通的,因为在编译器编译过后出来的字节码已经去掉了实际的参数类型。
另外一种做法是写一个方法
           //定义一个方法对泛型中具体的参数类型进行操作
      public   static   void   applyGenic(Vector<Date> v1){
         
    }
定义这个方法之后,我没有办法通过v1来获得前面这个变量的类型,但是我们可以通过这个方法来知道他的参数列表的类型
Method applyMethod=GenicTest.  class .getMethod(   "applyGenic"   , Vector. class   );
Type[] types=applyMethod.getGenericParameterTypes(); //这里指得到参数的泛型,返回的是一个Type[]数组
ParameterizedType pType=(ParameterizedType)types[0]; //ParameterizedType是Type下面的子类,是参数化类型
System.   out  .println(pType.getRawType()); //getRawType()这里获得是原始的类型
System.   out  .println(pType.getActualTypeArguments()[0]);  //getActualTypeArguments()[0]获得的实际的参数类型
4.小应用案例:
/*对java泛型的综合应用案例:
1.利用HashMap指定一个参数化类型的变量用来存储集合数据HashMap<k,v>指定一个key和value,key和value是一一对应的,现在的问题是要利用迭代来取出其中的key和value
2.由于Map没有实现 Iterable<E> 接口所以不能进行迭代,而Set实现了 Iterable<E> 接口可以进行迭代
3.所以现在思考的问题就是要将HashMap转换为Set,则利用到HashMap中的一个方法entrySet(),返回值是Set,而这里要注意的是Set的类型化参数也是一个泛型
         */
HashMap<String, Integer> maps =  new  HashMap<String, Integer>();
maps.put(   "djkf"  , 33);
maps.put(   "sdfh"  , 25);
maps.put(   "sdkjf"  , 78);
         
Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();
for  (Map.Entry<String, Integer> entry:entrySet){ //这里要注意对于迭代出来的类型是Map.Entry<String, Integer>,因为Set里面装的就是Map.Entry<String, Integer>
System.   out  .println(entry.getKey() +  ":"   + entry.getValue());
}
         
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Seven的代码实验室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值