由于类型擦除,java 中的泛型对象在运行时是不知道自己类型参数的类型的。
但有几种特殊情况,能够获取泛型对象的参数类型:
1、类中有 class 信息(类中有一个 Class 字段)
2、父类中有 class 信息(父类是泛型类,并指定了参数类型)
3、持有者中有 class 信息(是一个类的 Field、Method)
一、类中有 class 信息
类声明:
staticclassA1<T>{public Class<T> mClass;publicA1(Class<T> aClass){
mClass= aClass;}}
使用:
A1<String> a1=newA1<>(String.class);
System.out.println(a1.mClass);
输出:
classjava.lang.String
二、父类中有 class 信息
2.1 子类
类声明:
staticclassA2extendsA2Parent<String>{}staticclassA2Parent<T>{}
使用:
A2 a2=newA2();printClass(a2);publicstaticvoidprintClass(Object o){
System.out.println();format("o: ", o);format("class: ", o.getClass());format("superClass: ", o.getClass().getSuperclass());format("genericSuperClass: ", o.getClass().getGenericSuperclass());format("genericSuperClass typeArgument: ",((ParameterizedType) o.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);}
输出:
o: A2@28a418fcclass:classA2
superClass:classA2Parent
genericSuperClass: A2Parent<java.lang.String>
genericSuperClass typeArgument:classjava.lang.String
2.2 匿名子类
使用:
A2Parent<String> parent=newA2Parent<String>(){};printClass(parent);
输出:
o: $1@5305068aclass: $1
superClass: A2Parent
genericSuperClass: A2Parent<java.lang.String>
genericSuperClass typeArgument:classjava.lang.String
三、持有者中有 class 信息
类声明:
staticclassA3<T>{}staticclassA3User{
A3<String> a3=newA3<>();}
使用:
A3User a3User=newA3User();try{
Field field= FieldUtils.getField(a3User.getClass(),"a3");
System.out.println(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);}catch(Exception e){
e.printStackTrace();}
输出:
classjava.lang.String