Java中定义泛型<T>时,怎么获得泛型的类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中定义泛型<T>时,怎么获得泛型的类型相关的知识,希望对你有一定的参考价值。

T.getClass()或者T.class都是非法的,因为T是泛型变量。
由于一个类的类型是什么是在编译期处理的,故不能在运行时直接在Base里得到T的实际类型。
有一种变通的实现方式:
import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class Generic extends Base<String>
public static void main(String[] args)
Generic c = new Generic();
System.out.println(c.array);


Object array ;
public Generic()
array = Array.newInstance(getGenericType(0), 100);



class Base<T>
public Class getGenericType(int index)
Type genType = getClass().getGenericSuperclass();
if (!(genType instanceof ParameterizedType))
return Object.class;

Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0)
throw new RuntimeException("Index outof bounds");

if (!(params[index] instanceof Class))
return Object.class;

return (Class) params[index];


其中Base<T>是泛型类,在父类中声明getGenericType,子类继承具体的Base<String>,那么在子类中就可以通过getGenericType(0)获取到String的class
参考技术A "<T>"可以代表任意类型的。
解释: “<T>”是泛型的默认值,可以被任意类型所代替,如:
List<String> list = new ArayList<String>();这个就定义了一个String类型的数组,那么T的类型就是字符串。
List<T> list = new ArayList<T>();之后也有可以:list.add("StringBatch");
这个时候T的类型也是String。也就是说T是动态的,可以被任意指定类型。

如何在运行时获取泛型的类型

在父类的构造方法中,获取泛型的具体类型
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import com.opensymphony.xwork2.ModelDriven;
/**
* 工具类直接返回ModelDriven的对象
*/
public class ModelBaseAction<T> extends BaseAction implements ModelDriven<T>
protected T model;
/**
* 通过反射,获取泛型的具体类型并实例化这个类型
*/
public ModelBaseAction()
// 获取反射的类型
java.lang.reflect.Type cls = super.getClass().getGenericSuperclass();
if (cls instanceof ParameterizedType)
ParameterizedType pt = (ParameterizedType) cls;
// 获取所有放到泛型里面的类型
Type[] tps = pt.getActualTypeArguments();
System.err.println(tps[0].getTypeName());
try
// 实例化这个泛型所代表的类对象
model = (T) Class.forName(tps[0].getTypeName()).newInstance();
catch (Exception e)
throw new RuntimeException("没有默认构造方法", e);



@Override
public final T getModel()
return model;


参考技术A java 的泛型在jdk1.5 以后添加 在运行时采用的是擦除的机制 也就是说泛型只在编译器才进行检查 运行时会向上线进行擦除 如果没有指定上线的话就会擦除为object 所以你取不到

以上是关于Java中定义泛型<T>时,怎么获得泛型的类型的主要内容,如果未能解决你的问题,请参考以下文章

javapoet添加泛型参数问题,怎么解决

Java中声明泛型方法

C#实体类中如何定义泛型集合类型的属性

java中一个方法的返回值可能是integer或者Double,请问该怎么定义泛型接收

如何在运行时获取泛型的类型

java中返回值类型<T> T 这两个T分别代表啥?