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); } } }
- System.out.println(String.class.isAssignableFrom(Object.class));
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; }
- }
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();
- }
- }
- }
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,