获取java参数化类中泛型的具体类型

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/junranhuigu/article/details/72676371
最近闲来无事,造个json的轮子练练手。其中遇到一个问题:
如何获取List<T>中的T.class?
衍生出来的问题就是:如何获取java中参数化类中泛型的具体类型?


几经查询将网上得到的方法进行汇总:
关键是ParameterizedType这个接口
关于ParameterizedType以及Type接口的详细说明,可以看下面这篇文章:
Java泛型Type


如果你懒得看说明文章,我按照我的理解简单说一下(如有不对,还请指正):
就是对于这个问题只能通过java中的反射方式去获取,而在通过反射获取参数化类的过程中,会生成ParameterizedType这个接口以统一标示参数化类中的泛型具体类型的内容。我们只需要获取这个接口然后调用 ParameterizedType.getActualTypeArguments()  这个方法即可获取泛型的具体类型


想要获取ParameterizedType这个接口我收集到的有两种方式,但都无法直接获取

第一种是通过读取 将该参数化类作为成员的类 的成员来获取,具体代码如下:

/**
 * 这是泛型类
 * */
public class ItemVo {
	protected int id;
	protected int count;
	
	public ItemVo() {
		// TODO Auto-generated constructor stub
	}
	
	public ItemVo(int id, int count) {
		this.id = id;
		this.count = count;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	
	@Override
	public String toString() {
		return getClass().getSimpleName() + " " + id + " " + count;
	}
}
import com.server.java.entity.bean.vo.item.ItemVo;

public class Test {
	private List<ItemVo> itemlist;//我们要获取的泛型类型为ItemVo
	private Map<Integer, ItemVo> itemMap;//我们要获取的泛型类型为Integer和ItemVo
	
	public Test() {
		itemlist = new ArrayList<>();
		itemMap = new HashMap<>();
	}
	
	public static void main(String args[]) throws Exception{
		//获取成员itemlist
		Field field = Test.class.getDeclaredField("itemlist");
		System.out.println(field);
		
		Type t = field.getGenericType();
		ParameterizedType pt = (ParameterizedType) t;
		Type[] ts = pt.getActualTypeArguments();//这样就获取了List<ItemVo>中的泛型
		for(int i = 0; i < ts.length; ++ i){
			System.out.println(i + " itemlist中的泛型为:" + ts[i]);
			Class<?> c = (Class<?>) ts[i];//如果需要使用这个类型 进行强转即可
			System.out.println(i + " 强转后类型为:" + c);
		}
		System.out.println("*************************************************************");
		//获取成员itemMap
		field = Test.class.getDeclaredField("itemMap");
		System.out.println(field);
		
		t = field.getGenericType();
		pt = (ParameterizedType) t;
		ts = pt.getActualTypeArguments();//这样就获取了Map<Integer, ItemVo>中的泛型
		for(int i = 0; i < ts.length; ++ i){
			System.out.println(i + " itemMap中的泛型为:" + ts[i]);
			Class<?> c = (Class<?>) ts[i];//如果需要使用这个类型 进行强转即可
			System.out.println(i + " 强转后类型为:" + c);
		}
		
	}
}

运行输出结果如下:

private java.util.List com.server.test.Test.itemlist
0 itemlist中的泛型为:class com.server.java.entity.bean.vo.item.ItemVo
0 强转后类型为:class com.server.java.entity.bean.vo.item.ItemVo
*************************************************************
private java.util.Map com.server.test.Test.itemMap
0 itemMap中的泛型为:class java.lang.Integer
0 强转后类型为:class java.lang.Integer
1 itemMap中的泛型为:class com.server.java.entity.bean.vo.item.ItemVo
1 强转后类型为:class com.server.java.entity.bean.vo.item.ItemVo

第二种是通过读取 将该参数化类作为父类的子类 的父类成员来获取,具体代码如下:

依旧使用ItemVo类,该类代码见上

测试代码如下:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;

import com.server.java.entity.bean.vo.item.ItemVo;

public class Test extends ArrayList<ItemVo>{
	
	private static final long serialVersionUID = -1375958143091889386L;

	public static void main(String args[]) throws Exception{
		//获取Test类的父类ArrayList<ItemVo>的Type
		Type t = Test.class.getGenericSuperclass();
		ParameterizedType pt = (ParameterizedType) t;
		Type[] ts = pt.getActualTypeArguments();//这样就获取了ArrayList<ItemVo>中的泛型
		for(int i = 0; i < ts.length; ++ i){
			System.out.println(i + " 父类中的泛型为:" + ts[i]);
			Class<?> c = (Class<?>) ts[i];//如果需要使用这个类型 进行强转即可
			System.out.println(i + " 强转后类型为:" + c);
		}
	}
}

运行输出结果如下:

0 父类中的泛型为:class com.server.java.entity.bean.vo.item.ItemVo
0 强转后类型为:class com.server.java.entity.bean.vo.item.ItemVo

如有疑问或批评指正,请在评论区留言

展开阅读全文

没有更多推荐了,返回首页