方法一:TypeToken
TypeToken 是google提供的一个解析Json数据的类库中一个类;
不会有泛型擦除的风险,TypeToken则不是直接利用反射,而是曲线救国:创建一个TypeToken的匿名继承类。由于匿名类的申明信息中保留了泛型信息,通过反射可得…
泛型擦除:List 编译后List
public void getIntegerType() {
final TypeToken typeToken = new TypeToken<List<Integer>>() {};
//java.util.List<java.lang.Integer>
//上面使用TypeToken的目的是为了在运行时获取List<T>的泛型类型Integer,反射则办不到。
//类型擦除机制,.class的LocalVariableTable属性中只会保留Ljava/util/ArrayList,
//不会是 Ljava/util/ArrayList<Ljava/lang/Integer;> )
final Type type = typeToken.getType();
}
方法二:java.lang.reflect.ParameterizedType && Type
Type 是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
API中提到的Type的组成部分说明如下:
原始类型:一般意义上的java类,由class类实现
参数化类型:ParameterizedType接口的实现类
数组类型:GenericArrayType接口的实现类
类型变量:TypeVariable接口的实现类
基本类型:int,float等java基本类型,其实也是class
1,当我们拿到一个Class,用Class. getGenericInterfaces()方法得到Type[],也就是这个类实现接口的Type类型列表。
2,当我们拿到一个Class,用Class.getDeclaredFields()方法得到Field[],也就是类的属性列表,然后用Field. getGenericType()方法得到这个属性的Type类型。
3,当我们拿到一个Method,用Method. getGenericParameterTypes()方法获得Type[],也就是方法的参数类型列表。
demo
/**
* @describe:
* @author:zqm
*/
public class RefectTestController<T,R> {
private Class<T> clazz;
private Class<R> clazzR;
public RefectTestController() {
TypeToken<T> classType = new TypeToken<T>(getClass()) {};
clazz = (Class<T>) classType.getRawType();
TypeToken<R> classTypeR = new TypeToken<R>(getClass()){};
clazzR = (Class<R>) classTypeR.getRawType();
System.out.println(clazz);
System.out.println(clazzR);
// 0,1表示泛型参数的顺序
Class <T> entityClass = (Class <T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
Class <R> entityClassR = (Class <R>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
System.out.println(entityClass);
System.out.println(entityClassR);
}
public static class GT1 extends RefectTestController<RegularExpressionController,ScheduleController> {
public static void main(String[] args) {
System.out.println(new GT1().getClass().getGenericSuperclass());
}
}
}
**
结果:
**