加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

聊一聊Java 泛型全解

发布时间:2019-08-29 22:37:28 所属栏目:优化 来源:来一杯82年的Java
导读:副标题#e# 对于java的泛型我一直属于一知半解的,平常真心用的不多。直到阅读《Effect Java》,看到很多平常不了解的用法,才下定决心,需要系统的学习,并且记录下来。 1、泛型的概述: 1.1 泛型的由来 根据《Java编程思想》中的描述,泛型出现的动机: 有

3.2 验证实例:

  1. public class GenericTest { 
  2.  public static void main(String[] args) { 
  3.  new GenericTest().testType(); 
  4.  } 
  5.  public void testType(){ 
  6.  ArrayList<Integer> collection1 = new ArrayList<Integer>(); 
  7.  ArrayList<String> collection2= new ArrayList<String>(); 
  8.   
  9.  System.out.println(collection1.getClass()==collection2.getClass()); 
  10.  //两者class类型一样,即字节码一致 
  11.   
  12.  System.out.println(collection2.getClass().getName()); 
  13.  //class均为java.util.ArrayList,并无实际类型参数信息 
  14.  } 

输出结果:

  1. true 
  2. java.util.ArrayList 

分析:

这是因为不管为泛型的类型形参传入哪一种类型实参,对于Java来说,它们依然被当成同一类处理,在内存中也只占用一块内存空间。从Java泛型这一概念提出的目的来看,其只是作用于代码编译阶段,在编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦出,也就是说,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段。

在静态方法、静态初始化块或者静态变量的声明和初始化中不允许使用类型形参。由于系统中并不会真正生成泛型类,所以instanceof运算符后不能使用泛型类

4、泛型与反射

把泛型变量当成方法的参数,利用Method类的getGenericParameterTypes方法来获取泛型的实际类型参数

例子:

  1. public class GenericTest { 
  2.  public static void main(String[] args) throws Exception { 
  3.  getParamType(); 
  4.  } 
  5.   
  6.  /*利用反射获取方法参数的实际参数类型*/ 
  7.  public static void getParamType() throws NoSuchMethodException{ 
  8.  Method method = GenericTest.class.getMethod("applyMap",Map.class); 
  9.  //获取方法的泛型参数的类型 
  10.  Type[] types = method.getGenericParameterTypes(); 
  11.  System.out.println(types[0]); 
  12.  //参数化的类型 
  13.  ParameterizedType pType = (ParameterizedType)types[0]; 
  14.  //原始类型 
  15.  System.out.println(pType.getRawType()); 
  16.  //实际类型参数 
  17.  System.out.println(pType.getActualTypeArguments()[0]); 
  18.  System.out.println(pType.getActualTypeArguments()[1]); 
  19.  } 
  20.  /*供测试参数类型的方法*/ 
  21.  public static void applyMap(Map<Integer,String> map){ 
  22.  } 

输出结果:

  1. java.util.Map<java.lang.Integer, java.lang.String> 
  2. interface java.util.Map 
  3. class java.lang.Integer 
  4. class java.lang.String 

通过反射绕开编译器对泛型的类型限制

  1. public static void main(String[] args) throws Exception { 
  2.         //定义一个包含int的链表 
  3.         ArrayList<Integer> al = new ArrayList<Integer>(); 
  4.         al.add(1); 
  5.         al.add(2); 
  6.         //获取链表的add方法,注意这里是Object.class,如果写int.class会抛出NoSuchMethodException异常 
  7.         Method m = al.getClass().getMethod("add", Object.class); 
  8.         //调用反射中的add方法加入一个string类型的元素,因为add方法的实际参数是Object 
  9.         m.invoke(al, "hello"); 
  10.         System.out.println(al.get(2)); 
  11.     } 

5 泛型的限制

5.1 模糊性错误

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读