java 含多级父类时 映射获取指定字段类型、值 并根据类型修改值

切面编程中有一个场景,req中肯定有projectIds字段有的是List<Long> projectIds有的是Set<Long> projectIds,需要先获取原来projectIds值,根据逻辑处理后修改projectIds, 如果原来是List<Long>类型肯定在修改赋值时是List<Long>类型否则对应Set<Long>类型。且req集成了父类,父类又集成了父类,projectId不一定在哪个父类中。传统的映射获取值直接报错,参考下面工具类循环去父类中查找projectIds字段后获取再修改。

含多级父类时指定字段不一定在子级或哪个父级时,可循环映射获取到指定字段值和类型。封装了工具类(ReflectionUtils.java)如下:

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

public class ReflectionUtils {

    /**
     * 可获取父类和子类的所有方法
     * @param object
     * @param methodName
     * @param parameterTypes
     * @return
     */
    public static Method getDeclaredMethod(Object object, String methodName, Class<?> ... parameterTypes)
    {
        Method method = null ;
        for(Class<?> clazz = object.getClass() ; clazz != Object.class ; clazz = clazz.getSuperclass())
        {
            try {
                method = clazz.getDeclaredMethod(methodName, parameterTypes) ;
                return method ;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static Field getDeclaredField(Object object, String methodName){
        Field fieldRes = null;
        Class<?> clazz = object.getClass();
        while (clazz != null && !Object.class.equals(clazz)) {
            Field field = getDeclaredFieldRecursively(clazz, methodName); // 要查询的属性名称
            if (field == null) {
//                System.out.println("未找到该属性!");
                break;
            } else {
                Type genericType = field.getGenericType(); // 获取属性的泛型类型
                if(methodName.equals(field.getName())){
                    fieldRes = field;
                    break;
                }
//                System.out.println("属性名称:" + field.getName());
//                System.out.println("属性泛型类型:" + genericType);
                clazz = clazz.getSuperclass(); // 递归调用父类
            }
        }
        return fieldRes;
    }

    private static Field getDeclaredFieldRecursively(Class<?> clazz, String propertyName) {
        try {
            return clazz.getDeclaredField(propertyName);
        } catch (NoSuchFieldException e) {
            if (clazz.getSuperclass() != null) {
                return getDeclaredFieldRecursively(clazz.getSuperclass(), propertyName);
            } else {
                throw new RuntimeException("无法找到属性:" + propertyName);
            }
        }
    }
}

比如获取 projectIds字段是List<Long>还是 Set<Long>类型,然后根据类型赋值后修改值