java 判断泛型的类型_java 通过反射获取泛型的类型

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

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

Account聚合AccountItem,AccountItem聚合Prodcut。

都是用List和List来表示的

我要实现一个功能,需要动态的传入一个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 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。

4、getGenericSuperclass, getSuperclass, getActualTypeArguments

说明

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

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

例子

1.ClassA.java

public class ClassA {

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 extends ClassA{

private List 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

----------->getActualTypeArguments:T,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值