在使用策略模式设计了一个抽象服务类,该类有一个泛型,在程序中又需要该泛型指向的class,代码参考如下:
public abstract class AbstractService<T> {
private Class<T> tclazz;
public Class<T> getTClass(){
return tclazz;
}
public AbstractService() {
//tclazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
ParameterizedType parameterizedType = getParameterizedType(getClass());
Type[] params = parameterizedType.getActualTypeArguments();
tclazz = getClazz(params[0]);
}
/**
* 递归获取 ParameterizedType
* (对于一个实现类,它有可能是父类的父类才是 AbstractService)
*
*/
private ParameterizedType getParameterizedType(Type type){
if(type instanceof ParameterizedType){
return (ParameterizedType) type;
}else if(type instanceof Class){
return getParameterizedType((((Class<?>) type).getgetGenericSuperclass()));
}else{
return null;
}
}
/**
* 递归获取 Class
* (对于一个实现类,它有可能是父类的父类才是 AbstractService)
*
*/
private Class getClazz(Type type){
if(type instanceof ParameterizedType){
Type rawType = ((ParameterizedType) type).getRawType();
return getClazz(rawType);
}else{
return (Class) type;
}
}
}
几个重要的方法
public Type getGenericSuperclass()
用来返回表示当前Class 所表示的实体(类、接口、基本类型或 void)的直接超类的Type。如果这个直接超类是参数化类型的,则返回的Type对象必须明确反映在源代码中声明时使用的类型。比如:
import java.lang.reflect.ParameterizedType;
public class AAService extends AbstractService<Integer>{
public static void main(String[] args) {
System.out.println(((ParameterizedType)new AAService().getClass().getGenericSuperclass()));
}
}
则输出结果即为:
AbstractService
如果此Class代表的是Object 类、接口、基本类型或 void,则返回 null。。如果此对象表示一个数组类,则返回表示 Object 类的 Class 对象。
public Type[] getGenericInterfaces()
与上面那个方法类似,只不过Java的类可以实现多个接口,所以返回的Type必须用数组来存储。
以上两个方法返回的都是Type对象或数组,在我们的这个话题中,Class都是代表的参数化类型,因此可以将Type对象Cast成ParameterizedType对象。
ParameterizedType
ParameterizedType对象有一个方法, getActualTypeArguments()。
public Type[] getActualTypeArguments() 用来返回一个Type对象数组,这个数组代表着这个Type声明中实际使用的类型。
超类中获取T.class
子类在继承具有泛型的超类时,会自动调用超类的构造方法。在此超类的构造方法中,调用的getClass返回的是子类的Class类型