• java 通过反射获取泛型的类型


    jdk1.5开始支持泛型,所以我们有时需要把泛型里定义的对象的类型拿到

    比如现在我定义了三个类Account, AccountItem和Product类。

    Account聚合AccountItem,AccountItem聚合Prodcut。

    都是用List<AccountItem>和List<Product>来表示的

    我要实现一个功能,需要动态的传入一个Class的类型,然后反射到启动的List,根据List里定义的泛型,知道其中List的具体对象。

    这个需求主要是由于现在的Json-lib还不支持深度的List的unmarshall,而只支持数组的方式。其实这里就是json-lib的beanfactory用到ezmorpher,而ezmorpher不支持泛型的定义方式,所以不知道类型,全转成MorpherDynBean,这样的对象是我们不需要的。

    这样需要修改ezmorpher的代码,注入自己的MorpherBean的processor,这个processor就根据泛型拿到,我们需要转型的对象。
    代码片段如下

     Field[] fs = clazz.getDeclaredFields(); // 得到所有的fields
    
    for(Field f : fs) 
    { 
        Class fieldClazz = f.getType(); // 得到field的class及类型全路径
    
        if(fieldClazz.isPrimitive())  continue;  //【1】 //判断是否为基本类型
    
        if(fieldClazz.getName().startsWith("java.lang")) continue; //getName()返回field的类型全路径;
    
        if(fieldClazz.isAssignableFrom(List.class)) //【2】
        { 
                 Type fc = f.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型
    
                 if(fc == null) continue;
    
                 if(fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型 
                { 
                       ParameterizedType pt = (ParameterizedType) fc;
    
                       Class genericClazz = (Class)pt.getActualTypeArguments()[0]; //【4】 得到泛型里的class类型对象。
    
                       m.put(f.getName(), genericClazz);
    
                       Map<String, Class> m1 = prepareMap(genericClazz);
    
                       m.putAll(m1); 
                 } 
          } 
    }
    

     【解释】:
    1、isPrimitive

    public boolean isPrimitive()判定指定的 Class 对象是否表示一个基本类型。
    有九种预定义的 Class 对象,表示八个基本类型和 void。这些类对象由 Java 虚拟机创建,与其表示的基本类型同名,即 boolean、byte、char、short、int、long、float 和 double。 【注:像Integer,Boolean等包装类不是基本类型!】

    这些对象仅能通过下列声明为 public static final 的变量访问,也是使此方法返回 true 的仅有的几个 Class 对象。 

    返回: 当且仅当该类表示一个基本类型时,才返回 true
    从以下版本开始:JDK1.1
    2、isAssignableFrom

    System.out.println(String.class.isAssignableFrom(Object.class));   
    

     2.//打印true  
        AA.class.isAssignableFrom(BB.class)的作用是判定AA表示的类或接口是否同参数BB指定的类表示的类或接口相同,或AA是否是BB的父类。

               System.out.println( String.class.isAssignableFrom(Object.class) ) ;       false
             System.out.println( Object.class.isAssignableFrom(Object.class) );       true
             System.out.println( Object.class.isAssignableFrom(String.class) );        true
             String ss = "";   
             System.out.println( ss instanceof Object );                                            true
             Object o = new   Object();
             System.out.println( o instanceof Object );                                              true
    

     3、ParameterizedType 表示参数化类型,如 Collection<String>。

    4、getGenericSuperclass, getSuperclass, getActualTypeArguments

         说明

               1.Class<? super T> getSuperclass():返回本类的父类

               2.Type getGenericSuperclass():返回本类的父类,包含泛型参数信息

          例子
              1.ClassA.java

                 public class  ClassA <T>{     
                     private T obj;     
                     public void setObject(T obj) {      this.obj = obj;  }   
                     public T getObject() {    return obj;   }     
               }  
    

     2.Test.java

     
    import java.lang.reflect.Type;    
    import java.lang.reflect.ParameterizedType;   
    public class Test<T> extends ClassA<T>{   
    	private List<String> list;   
    
        public void testA(){
        	Type t = Test.class.getDeclaredField("list").getGenericType();
        	if (ParameterizedType.class.isAssignableFrom(t.getClass())) {            
        		for (Type t1:((ParameterizedType)t).getActualTypeArguments()) {        
        			System.out.print(t1 + ",");        
        		}        
        		System.out.println();        
        	} 
       }
       public static void main(String args[]) throws Exception{     
                System.out.println("======getSuperclass======:");    
                System.out.println(Test.class.getSuperclass().getName());   
                System.out.println("======getGenericSuperclass======:");   
                Type t = Test.class.getGenericSuperclass();    
                System.out.println(t);     
                if (ParameterizedType.class.isAssignableFrom(t.getClass())) {  
                         System.out.print("----------->getActualTypeArguments:");     
                         for (Type t1:((ParameterizedType)t).getActualTypeArguments()) {     
                                        System.out.print(t1 + ",");     
                          }     
                         System.out.println();     
                }  
       }   
    
      }  
    

     输出结果:
    class java.lang.String,
                        ======getSuperclass======:
                        ClassA
                        ======getGenericSuperclass======:
                        ClassA<T>
                        ----------->getActualTypeArguments:T,

  • 相关阅读:
    win10- *.msi 软件的安装,比如 SVN安装报2503,2502
    Java-byte[]与16进制字符串互转
    log4j 日志脱敏处理 + java properties文件加载
    CentOS7编译安装SVN(subversion1.9.7)
    Samba安装与配置
    php 实现redis发布订阅消息及时通讯
    PHP中使用ActiveMQ实现消息队列
    sphinx 配置文件全解析
    nginx和apache 配置
    php实现汉诺塔问题
  • 原文地址:https://www.cnblogs.com/smile361/p/2811819.html
Copyright © 2020-2023  润新知