学习了动态初始化类,如果参数是各种类型的,要如何处理呢?
这时候,需要用到泛型,而传的数据是实体类型,如果从泛型中获取实体类型呢?
需要使用反射,获得指定类的父类的泛型参数的实际类型,直接上代码
getSuperClassGenricType
public class GenericUtils {
/**
* 通过反射,获得指定类的父类的泛型参数的实际类型
*
* @param clazz clazz 需要反射的类,该类必须继承范型父类
* @param index 泛型参数所在索引,从0开始.
* @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,
* 所以直接返回<code>Object.class</code>
*/
public static Class getSuperClassGenricType(final Class clazz, final int index) throws IndexOutOfBoundsException {
//得到泛型父类
Type genType = clazz.getGenericSuperclass();
//如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
//返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
return Object.class;
}
if (params[index] instanceof ParameterizedType) {
return (Class) ((ParameterizedType) params[index]).getRawType();
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
}
参数转换
private static final ObjectMapper MAPPER = new ObjectMapper();
private I exchangeParam(Object data) throws IOException {
Class requestGenricType = GenericUtils.getSuperClassGenricType(getClass(), 0);
if (!Map.class.isAssignableFrom(requestGenricType)) {
return (I) MAPPER.readValue(MAPPER.writeValueAsString(data), requestGenricType);
}
return (I) data;
}
根据类型,使用mapper转换值
关于type:
package java.lang.reflect;
/**
* Type是Java中所有类型的常用超级接口编程语言
* 这些包括原始类型,参数化类型,数组类型,类型变量和基本数据类型类型。
*
* @since 1.5
*/
public interface Type {
/**
* Returns a string describing this type, including information
* about any type parameters.
*
* @implSpec The default implementation calls {@code toString}.
*
* @return a string describing this type
* @since 1.8
*/
default String getTypeName() {
return toString();
}
}
ParameterizedType,GenericArrayType,TypeVariable,WildcardType和Class类型的接口介绍:
(1)ParameterizedType:表示一种参数化的类型,比如Collection。获取参数化类型<>的实际类型,无论<>中有几层<>嵌套,这个方法仅仅脱去最外层的<>之后剩下的内容就作为这个方法的返回值。
(2)GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型
(3)TypeVariable:是各种类型变量的公共父接口
(4)WildcardType:代表一种通配符类型表达式,比如?, ? extends Number, ? super Integer。
Type[] getUpperBounds() -- 返回泛型类型变量的上界
Type[] getLowBounds() -- 返回泛型类型变量的下界
(5)Class 表示原始类型,其对象表示JVM中的一个类和接口。
总结:
参数泛化后,在处理的时候要获取实体类型,这样才能进行参数转换。这个需要多看一些代码,才能够了解,更好的理解。
具体的应用看《动态初始化类+参数泛型化》