切面编程中有一个场景,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>类型,然后根据类型赋值后修改值