范型的实际类型的解析工具类——笔记
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* Description:
* 范型工具类<br/>
* 通过反射,<br/>
* 获取指定类的父类的泛型参数的实际类型;<br/>
* 获得方法返回值泛型参数的实际类型;<br/>
* 获得方法输入参数第index个输入参数的所有泛型参数的实际类型;<br/>
* 获得Field泛型参数的实际类型<br/>
* @author zwl
* @version 1.0
* @date 2020/6/2 8:19
*/
public class GenericsUtils {
/**
* 通过反射,获得指定类的父类的泛型参数的实际类型. 如 BuyerServiceBean extends DaoSupport<Buyer>
*
* @param clazz clazz 需要反射的类,该类必须继承范型父类
* @param index 泛型参数所在索引,从0开始.
* @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static Class<?> getSuperClassGenricType(Class<?> clazz, int index) {
// 得到泛型公共父类Type
Type genType = clazz.getGenericSuperclass();
// 如果没有实现ParameterizedType接口,即不支持泛型,直接返回null
if (!(genType instanceof ParameterizedType)) {
return null;
}
// 返回表示此类型实际类型参数的Type对象的数组,数组里放的都是对应类型的Class
// 如BuyerServiceBean extends DaoSupport<Buyer,Contact>就返回Buyer和Contact类型
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数"));
}
// 如果返回的不是Class类型或其子类类型,直接返回null
if (!(params[index] instanceof Class)) {
return null;
}
// 返回指定索引的范型参数
return (Class<?>) params[index];
}
/**
* 通过反射,获得指定类的父类的第一个泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer>
*
* @param clazz clazz 需要反射的类,该类必须继承泛型父类
* @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static Class<?> getSuperClassGenricType(Class<?> clazz) {
return getSuperClassGenricType(clazz, 0);
}
/**
* 通过反射,获得方法返回值泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){}
*
* @param method 指定方法的java.lang.reflect.Method类型
* @param index 泛型参数所在索引,从0开始.
* @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static Class<?> getMethodGenericReturnType(Method method, int index) {
Type returnType = method.getGenericReturnType();
return getArgumentTypeClass(index, returnType);
}
/**
* 通过反射,获得方法返回值第一个泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){}
*
* @param method 指定方法的java.lang.reflect.Method类型
* @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static Class<?> getMethodGenericReturnType(Method method) {
return getMethodGenericReturnType(method, 0);
}
/**
* 通过反射,获得方法输入参数第index个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){}
*
* @param method 指定方法的java.lang.reflect.Method类型
* @param index 第几个输入参数
* @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static List<Class<?>> getMethodGenericParameterTypes(Method method, int index) {
List<Class<?>> results = new ArrayList<Class<?>>();
Type[] genericParameterTypes = method.getGenericParameterTypes();
if (index >= genericParameterTypes.length || index < 0) {
throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数"));
}
Type genericParameterType = genericParameterTypes[index];
if (genericParameterType instanceof ParameterizedType) {
ParameterizedType aType = (ParameterizedType) genericParameterType;
Type[] parameterArgTypes = aType.getActualTypeArguments();
for (Type parameterArgType : parameterArgTypes) {
Class<?> parameterArgClass = (Class<?>) parameterArgType;
results.add(parameterArgClass);
}
return results;
}
return null;
}
/**
* 通过反射,获得方法输入参数第一个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){}
*
* @param method 方法
* @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static List<Class<?>> getMethodGenericParameterTypes(Method method) {
return getMethodGenericParameterTypes(method, 0);
}
/**
* 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names;
*
* @param field 字段
* @param index 泛型参数所在索引,从0开始.
* @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static Class<?> getFieldGenericType(Field field, int index) {
Type genericFieldType = field.getGenericType();
return getArgumentTypeClass(index, genericFieldType);
}
/**
* 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names;
*
* @param field 字段
* @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
public static Class<?> getFieldGenericType(Field field) {
return getFieldGenericType(field, 0);
}
/**
* 获取指定下标,泛型参数的实际类型
*
* @param index 泛型参数所在索引,从0开始.
* @param genericFieldType 原类型,参数化类型,数组类型,类型变量和原始类型的公共高级
* @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回null
*/
private static Class<?> getArgumentTypeClass(int index, Type genericFieldType) {
if (genericFieldType instanceof ParameterizedType) {
ParameterizedType aType = (ParameterizedType) genericFieldType;
Type[] fieldArgTypes = aType.getActualTypeArguments();
if (index >= fieldArgTypes.length || index < 0) {
throw new RuntimeException("你输入的索引" + (index < 0 ? "不能小于0" : "超出了参数的总数"));
}
return (Class<?>) fieldArgTypes[index];
}
return null;
}
}
### 如果觉得不错,来关注吧