通过反射得到泛型的类型参数

来源:互联网 发布:图书在版编目数据 编辑:程序博客网 时间:2024/05/21 20:41

小龙我在做项目的时候遇到了一些难题,当时我为了使我的代码最大的得到重用,我用泛型定义了一些类,可是在这个过程中遇到了一些困难,下面,我将我用反射技术解决我碰到的难题的一些知识分享给大家,希望大家喜欢。

首先,我定义的一个子类继承了一个带有泛型的父类,可是我想得到这个父类泛型的参数类型,思考了很久,感觉只有用反射才能解决这个问题!下面的代码是我用反射来解决这个问题的。

//这三个类是我模拟出来的,类的内容不是重点class Father<T,E> {}interface FatherInterface {}class Son extends Father<String,Integer> implements FatherInterface {}public class ReflectApplication {public static void main(String[] args) {FatherInterface fatherReference = new Son();//getClass()这个方法得到的永远都是运行时的类的字节码文件,//也就是说对于这个方法来说它不管继承,它只关心具体的对象是什么//然后得到这个对象的字节码文件System.out.println(fatherReference.getClass());// 下面我将介绍一下通过反射来获取// 首先,我们通过父类的引用得到子类的字节码文件Class subClass = fatherReference.getClass();//获取这个子类的父类的泛型参数的实际类型Type[] argumentTypes = getSuperClassGenricType(subClass);for (Type var : argumentTypes) {System.out.println(var);}}/** * 获得指定类的父类的泛型参数的实际类型 * @param clazz  子类型的字节码文件 * @return 返回父类泛型参数的实际类型的数组 */public static Type[] getSuperClassGenricType(Class subClass) {// 定义成泛型的类都会实现ParameterizedType接口Type type = subClass.getGenericSuperclass();if (type instanceof ParameterizedType) {// 如果是定义成泛型 的类,我们向上造型为这个接口ParameterizedType genericType = (ParameterizedType) type;// 用得到的这个接口得到泛型的所有泛型参数的实际类型Type[] argumentsType = genericType.getActualTypeArguments();return argumentsType;}return new Type[]{type};}}

那么,如果我定义一个方法,那么它的返回值也是泛型定义的类型,通过反射技术也依然可以获得其类型参数的实际类型。

public class ReflectApplication {public static void main(String[] args) throws Exception {Class clazz = ReflectApplication.class;Method method = clazz.getMethod("getNames",null);Type[] methodArgumentTypes = getMethodGenericReturnType(method);for (Type var : methodArgumentTypes) {System.out.println(var);}}/** * 这个方法并没有什么实际的意义,我只是模拟一下这种情况 */public Map<String, Integer> getNames() { return null; }/** *  * @param method   * @return  获得方法返回值泛型参数的实际类型数组 */public static Type[] getMethodGenericReturnType(Method method) {Type retType = method.getGenericReturnType();if (retType instanceof ParameterizedType) {// 如果是定义成泛型 的类,我们向上造型为这个接口ParameterizedType genericType = (ParameterizedType) retType;// 用得到的这个接口得到泛型的所有泛型参数的实际类型Type[] argumentsType = genericType.getActualTypeArguments();return argumentsType;}return new Type[]{retType};}}

下面通过反射获得获得方法输入参数的所有泛型参数的实际类型。

public class ReflectApplication {public static void main(String[] args) throws Exception {Class clazz = ReflectApplication.class;Method method = clazz.getMethod("nothing",Map.class,List.class);List<Type[]> list = getMethodGenericParameterTypes(method);int count = 0;for (Type[] types : list) {count = ++count;for(Type type : types) {System.out.print("第"+count+"个泛型参数的实际类型" + type + " ");}System.out.println();}}/** * 获得方法输入参数的所有泛型参数的实际类型 * @param method * @return */public static List<Type[]> getMethodGenericParameterTypes(Method method) {List<Type[]> list = new ArrayList<Type[]>();Type[] types = method.getGenericParameterTypes();for(Type var : types) {if (var instanceof ParameterizedType) {// 如果是定义成泛型 的类,我们向上造型为这个接口ParameterizedType genericType = (ParameterizedType) var;// 用得到的这个接口得到泛型的所有泛型参数的实际类型Type[] argumentTypes = genericType.getActualTypeArguments();list.add(argumentTypes);}}return list;}/** * 没有什么实际意义的类 * @param map * @param list */public void nothing(Map<String, Integer> map, List<String> list){}}

下面通过反射获得Field泛型参数的实际类型。

public class ReflectApplication {private Map<String,Integer> map = new HashMap<String, Integer>();public static void main(String[] args) throws Exception {Class clazz = ReflectApplication.class;Field field = clazz.getDeclaredField("map");Type[] types = getFieldGenericType(field);for (Type type : types) {System.out.println(type);}}/** * 获得Field泛型参数的实际类型 * @param method * @return */public static Type[] getFieldGenericType(Field field) {Type type = field.getGenericType();if (type instanceof ParameterizedType) {// 如果是定义成泛型 的类,我们向上造型为这个接口ParameterizedType genericType = (ParameterizedType) type;// 用得到的这个接口得到泛型的所有泛型参数的实际类型Type[] argumentTypes = genericType.getActualTypeArguments();return argumentTypes;}return new Type[]{type};}}


0 0
原创粉丝点击