做过Hibernate的朋友应该都知道,在我们的开发中,有很多的代码都是可以高度重用的,为了使代码高度重用,我们会使用泛型和反射机制来完成,但这个时候我们会遇到一个问题,那就是我们往往很难确定实体bean的具体类型。这个工具就是为了解决这些问题而开发的。
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;
/** * 泛型工具类 * @author lihuoming * */
public class GenericsUtils {
/** * 通过反射,获得指定类的父类的泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer> * * @param clazz clazz 需要反射的类,该类必须继承范型父类 * @param index 泛型参数所在索引,从0开始. * @return 范型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */
@SuppressWarnings({ "rawtypes" })
public static Class getSuperClassGenricType(Class clazz, int index) {
Type genType = clazz.getGenericSuperclass();//得到泛型父类
//如果没有实现ParameterizedType接口,即不支持泛型,直接返回Object.class
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
//返回表示此类型实际类型参数的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" : "超出了参数的总数"));
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
/** * 通过反射,获得指定类的父类的第一个泛型参数的实际类型. 如BuyerServiceBean extends DaoSupport<Buyer> * * @param clazz clazz 需要反射的类,该类必须继承泛型父类 * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */
@SuppressWarnings("rawtypes")
public static Class getSuperClassGenricType(Class clazz) {
return getSuperClassGenricType(clazz,0);
}
/** * 通过反射,获得方法返回值泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){} * * @param Method method 方法 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */
@SuppressWarnings("rawtypes")
public static Class getMethodGenericReturnType(Method method, int index) {
Type returnType = method.getGenericReturnType();
if(returnType instanceof ParameterizedType){
ParameterizedType type = (ParameterizedType) returnType;
Type[] typeArguments = type.getActualTypeArguments();
if (index >= typeArguments.length || index < 0) {
throw new RuntimeException("你输入的索引"+ (index<0 ? "不能小于0" : "超出了参数的总数"));
}
return (Class)typeArguments[index];
}
return Object.class;
}
/** * 通过反射,获得方法返回值第一个泛型参数的实际类型. 如: public Map<String, Buyer> getNames(){} * * @param Method method 方法 * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */
@SuppressWarnings("rawtypes")
public static Class getMethodGenericReturnType(Method method) {
return getMethodGenericReturnType(method, 0);
}
/** * 通过反射,获得方法输入参数第index个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){} * * @param Method method 方法 * @param int index 第几个输入参数 * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合 */
@SuppressWarnings("rawtypes")
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 results;
}
/** * 通过反射,获得方法输入参数第一个输入参数的所有泛型参数的实际类型. 如: public void add(Map<String, Buyer> maps, List<String> names){} * * @param Method method 方法 * @return 输入参数的泛型参数的实际类型集合, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回空集合 */
@SuppressWarnings("rawtypes")
public static List<Class> getMethodGenericParameterTypes(Method method) {
return getMethodGenericParameterTypes(method, 0);
}
/** * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names; * * @param Field field 字段 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */
@SuppressWarnings("rawtypes")
public static Class getFieldGenericType(Field field, int index) {
Type genericFieldType = field.getGenericType();
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 Object.class;
}
/** * 通过反射,获得Field泛型参数的实际类型. 如: public Map<String, Buyer> names; * * @param Field field 字段 * @param int index 泛型参数所在索引,从0开始. * @return 泛型参数的实际类型, 如果没有实现ParameterizedType接口,即不支持泛型,所以直接返回<code>Object.class</code> */
@SuppressWarnings("rawtypes")
public static Class getFieldGenericType(Field field) {
return getFieldGenericType(field, 0);
}
}