利用泛型获取泛型信息

---------------------- android培训java培训、期待与您交流! ----------------------

如何用反射来获取泛型信息


我们都知道泛型是给编译器看的,编译时会去掉泛型,那么在运行时,如果用反射来获取泛型信息呢,通过指定类对应的Class对象,可以获得该类里包含的所有Field,不管Field是使用private修饰,还是使用public修饰。获得了Field对象后,可以很容易的获得该Field的数据类型,即使用如下代码即可获得指定Field的类型。

//获取Field对象f的类型
	Class<?> clazz = f.getType();

但是这种方式只对普通类型的Field有效,如果该Field的类型是有泛型类型的类型,如Map<String,Integer>类型,则不能准确的得到该Field的泛型参数。
为了获得指定Field的泛型类型,应该用如下方法获取指定的泛型类型。

//获取Field实例的泛型类型
	Type gType = g.getGenericType();

然后将Type对象强制转换为ParameterizedType对象,ParameterizedType代表被参数化的类型,也就是增加了泛型限制的类型。
ParameterizedType 类提供了如下两个方法。
getRawType():返回没有泛型信息的原始类型。
getActualTypeArguments():返回泛型的参数类型

下面是一个获取泛型类型的完整程序:

package cn.itcast.test;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;

public class GenericTest{
	
	private Map<String,Integer> score;
	public static void main(String[] args) throws Exception{
		Class<GenericTest> clazz = GenericTest.class;
		Field field = clazz.getDeclaredField("score");
		//直接使用getType()方法取出Field类型只对普通Field类型有效
		Class<?> scoreType = field.getType();
		//下面仅输出java.util.Map
		System.out.println("score的类型是:" + scoreType);
		
		//获得Field实例的泛型类型
		Type gType = field.getGenericType();
		//如果gType类型是ParameterizedType对象
		if(gType instanceof ParameterizedType){
			//强制类型转换
			ParameterizedType pType = (ParameterizedType)gType;
			//获取原始类型
			Type rType = pType.getRawType();
			System.out.println("原始类型是:" + rType);
			
			//取得泛型类型的泛型参数
			Type[] tArgs = pType.getActualTypeArguments();
			System.out.println("泛型类型是:");
			for(int i = 0; i < tArgs.length; i++){
				System.out.println("第" + i + "个泛型类型是:" + tArgs[i]);
			}
		}else{
			System.out.println("获取泛型类型出错!");
		}

	}

}

程序运行结果:

score的类型是:interface java.util.Map
原始类型是:interface java.util.Map
泛型类型是:
第0个泛型类型是:class java.lang.String
第1个泛型类型是:class java.lang.Integer

从上面的运行结果可以看出,直接使用Field的getType()方法只能获取普通类型的Field数据类型,对于增加了泛型参数的类型Field,应该使用getGenericType()方法来取得其类型。

另外Type 也是java.lang.reflect包下的一个接口,该接口代表所有类型的公共高级接口,Class是Type接口的实现类,Type包括原始类型,参数化类型数组类型、类型变量和基本类型等。

ParameterizedType 表示参数化类型,如 Collection<String>。
Type getRawType() :返回 Type 对象,表示声明此类型的类或接口。

Type[] getActualTypeArguments():返回表示此类型实际类型参数的 Type 对象的数组。

 
注意,在某些情况下,返回的数组为空。如果此类型表示嵌套在参数化类型中的非参数化类型,则会发生这种情况。
因此应该先判断是否为参数化类型:

if(gType instanceof ParameterizedType){
			//强制类型转换
			ParameterizedType pType = (ParameterizedType)gType;
			//获取原始类型
			Type rType = pType.getRawType();
			System.out.println("原始类型是:" + rType);
			....
}

---------------------- android培训java培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net/heima 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值