`
lorry1113
  • 浏览: 256658 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

    博客分类:
  • 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,
分享到:
评论
2 楼 cuiqi4016 2015-11-30  
正在做json转换的功能,帮大忙了,感谢博主分享
1 楼 cxshun 2014-02-07  
写得很好,感谢博主的分享

相关推荐

    Java试题-3:反射和泛型的综合应用

    Java试题-3:反射和泛型的综合应用 Java反射 泛型都是比较高级的应用技术

    java 通过反射获取类上注解,方法上注解,注解里的值及方法参数

    java 通过反射获取类上注解,方法上注解,注解里的值及方法参数,项目为maven项目。导入时记得选择maven项目

    Java泛型的用法及T.class的获取过程解析

    主要介绍了Java泛型的用法及T.class的获取过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java泛型反射注解

    先说一下遇到的问题:通过使用GSON泛型进行报文转换的时候想要对部分关键字段加密,...解决过程:首先通过反射获取到bean下的对象名称。 对象名称获取到了之后需要获取对应的值 对值进行加密,然后再重新赋值到该对象

    654.652.JAVA基础教程_反射-获取运行时类的父类及父类的泛型(654).rar

    654.652.JAVA基础教程_反射-获取运行时类的父类及父类的泛型(654).rar

    反射处理java泛型

    当我们声明了一个泛型的接口或类,或需要一个子类继承至这个泛型类,而我们又希望利用反射获取这些泛型参数信息。这是本文将要介绍的ReflectionUtil是为了解决这类问题的辅助工具类,为java.lang.reflect标准库的...

    java中获取泛型类的子类

    通过反射获得指定类的父类的泛型参数的实际类型

    Java使用反射来获取泛型信息示例

    主要介绍了Java使用反射来获取泛型信息,结合实例形式分析了java基于反射操作泛型信息的相关实现技巧与注意事项,需要的朋友可以参考下

    JAVA反射机制详解视频

    (通过反射获取无参构造方法并使用) (通过反射获取带参构造方法并使用) (通过反射获取私有构造方法并使用) (通过反射获取成员变量并使用) (通过反射获取无参无返回值成员方法并使用) (通过反射获取带参带返回值成员...

    反射与泛型

    详细演示Java编程中通过子类获取传入父类DAO的泛型参数,并通过反射创建对象,并对其原理进行深度剖析

    Java泛型和反射.ppt

    泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?...在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。

    java反射知识点

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 我的代码里主要有一下知识点: 1.获取Class对象的三种方式 2.获取构造方法并调用 3.获取成员方法 4.获取成员变量 5.反射数组 6.通过反射...

    java反射工具类

    java的泛型和反射机制一直很难理解和应用,这个程序是关于反射和泛型的综合使用,主要实现获取一个类的属性名和方法,并可以获取属性值,存取属性值,属性名和属性值的字符串方式输出。只是个工具类,没有写测试类,...

    21-04-03_FactoryPattern(001_在工厂模式下以通过接口结合列表、泛型和反射等方式实现指定类型的实例化操作_控制台).rar

    在工厂模式下以通过接口结合列表、泛型和反射等方式实现指定类型的实例化操作

    Java开发技术大全(500个源代码).

    listConstructors.java 利用反射机制获取构造器列表 listFields.java 利用反射机制获取成员属性列表 listMethods.java 利用反射机制获取成员方法列表 loadClass.java 动态装载一个类 Shape.java 一个用于测试的...

    Java获取代码中方法参数名信息的方法

    在java中,可以通过反射获取到类、字段、方法签名等相关的信息,像方法名、返回值类型、参数类型、泛型类型参数等,但是不能够获取方法的参数名。在实际开发场景中,有时需要根据方法的参数名做一些操作,那么该如何...

    Java反射机制重点总结

    文章目录Java ReflectionJava反射机制提供的功能Java反射相关的主要APIjava.lang.Class类Class类的核心要点Class类的重要API实例实例化Class类对象(四种方法)创建类对象并获取类的完整结构获取Class对象后创建类的...

    Java反射简单例子

    使用class.forname利用反射创建类,然后再获取属性,方法,体现反射应用

    c# 反射获取传入对象的属性拼接sql语句实现增、删、改、查

    利用反射动态拼接sql。 daohelper属于DAL层,objectdata类属于BLL层,BLL层引用DAL层。映射数据的表继承objectdata类。例如,数据表book,根据字段与属性一一对应的方式创建book类,插入数据库时,直接book.save()

    java 面试常见问题整理

    Java 泛型了解么?什么是类型擦除?介绍一下常用的通配符? 常用的通配符有哪些? 你的项目中哪里用到了泛型? 反射 何为反射? 反射机制优缺点 反射的应用场景 注解 异常 Exception 和 Error 有什么区别? Checked ...

Global site tag (gtag.js) - Google Analytics