/**
* @param map ApiCode为必填 传参类型---> key:字段名称 value:【用-分割】例如->(动态接口内的参数名-入参类型[不必是必填]-是否为出参[默认false非必填]) beginTime-String-false
* @param MyClass 入参 例如Class=Test
* @param ClassPathName 入参类的完全限定名 例如com.zsj.Test
* @return
*/
private static List<TypedParam> DynamicParamsCore(Map<String, String> map, Object MyClass, String ClassPathName){
try {
Class<?> clazz = Class.forName(ClassPathName);
List<TypedParam> typedParamList = new ArrayList<>();
//用完了ApiCode就把他移除,避免遍历到
map.remove("ApiCode");
//设置一个集合用来存放使用过的字段,下面的动态设置值将排除这些使用过的
Map<String,String> UsedFields= new HashMap<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
//获取到key
String name = entry.getKey();
//获取到值值存放的是类型例如:Name-String-true
String[] values = entry.getValue().split("-");
String ParamName = values[0];
//通过map中的key获取类的字段
Field field = clazz.getDeclaredField(name);
//添加进入使用过的字段列表
UsedFields.put(name,"已使用");
//获取类型
Class<?> type = field.getType();
//获取到类型的名称
String simpleName = type.getSimpleName();
String typeName = simpleName;
if (values.length>1){
typeName=values[1];
}
boolean OutParam =false;
//如果有第2个参数那么设置第2个参数的值
if (values.length>2){
OutParam=Boolean.parseBoolean(values[1]);
}
//开启访问类型
field.setAccessible(true);
//判断是否能转换类
if (clazz.isInstance(MyClass)){
Object MyObject = clazz.cast(MyClass);
// 获取字段的值
Object value = field.get(MyObject);
TypedParam typedParam = new TypedParam();
typedParam.setParamName(ParamName);
typedParam.setParamType(typeName);
typedParam.setOutParam(OutParam);
typedParam.setParamValue(value);
typedParamList.add(typedParam);
} else {
// 如果MyClass不是clazz的实例
throw new ClassCastException("对象不能强制转换为" + ClassPathName+",请检查(完全限定名)是否输入正确");
}
}
//如果没有指定put中的值那么自动获取入参类中不为null的值设置进去,且名字为入参字段的值
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//设置允许访问
field.setAccessible(true);
if (clazz.isInstance(MyClass)){
Object MyObject = clazz.cast(MyClass);
String name = field.getName();
if (UsedFields.get(name)!=null) {
//如果该字段使用过则跳过,否则继续添加
continue;
}
Object value = field.get(MyObject);
if (value==null){
continue;
}
//获取类型
Class<?> type = field.getType();
//获取到类型的名称
String simpleName = type.getSimpleName();
TypedParam typedParam = new TypedParam();
typedParam.setParamName(name);
typedParam.setParamType(simpleName);
typedParam.setOutParam(false);
typedParam.setParamValue(value);
typedParamList.add(typedParam);
}
}
return typedParamList;
}catch (NoSuchFieldException e){
throw new RuntimeException("请检查传入的字段名称是否存在与当前的Class内,注意大小写一致"+e);
}catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 递归获取父类指定的字段
* @param clazz 类
* @param fieldName 字段名
* @return
* @throws NoSuchFieldException
*/
public static Field getFieldBySuperClass(Class<?> clazz, String fieldName) throws NoSuchFieldException {
try {
// 尝试在当前类中查找字段
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
// 如果当前类中没有找到,检查父类
Class<?> superClass = clazz.getSuperclass();
if (superClass != null) {
return getFieldBySuperClass(superClass, fieldName); // 递归调用
}
// 如果在所有父类中都没有找到,则抛出异常
throw e;
}
}
java反射实现类的属性自动封装
于 2024-08-04 09:08:42 首次发布