你见过屎山代码吗?来看看我辛辛苦苦写出来的屎山+Bug

531 阅读9分钟

目的

我想要实现两个任意类型之间的值以及Field字段之间的赋值,不仅仅只是简单的同类赋值,而是可以通过间接转换来进行实现值之间的赋值。例如你完全知道"1" 和 1可以相互转换赋值。{1,2,3,4,5} 和 [1,2,3,4,5] 和 {"1","2","3","4","5"}, "1,2,3,4,5" 等等之间其实是可以相互赋值转换的。数值类型和包装类型,字符串类型和任意类型。数组类型和集合类型。 下面是我的屎山代码实现链接:github.com/HK-hub/h-tr… 具体的类在这里:屎山代码

实现

DynamicValueHelper 类 和ReflectUtil 类:

package com.hk.transformation.core.helper;

import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.hk.transformation.core.annotation.dynamic.DynamicSwitch;
import com.hk.transformation.core.annotation.dynamic.DynamicValue;
import com.hk.transformation.core.constants.TransformationConstants;
import com.hk.transformation.core.reflect.converter.CollectionConverter;
import com.hk.transformation.core.reflect.converter.StringConverter;
import com.hk.transformation.core.reflect.util.ReflectUtil;
import com.hk.transformation.core.value.DynamicValueBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.*;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.core.annotation.AnnotationUtils;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @author : HK意境
 * @ClassName : DynamicValueHelper
 * @date : 2023/7/31 17:20
 * @description :
 * @Todo :
 * @Bug :
 * @Modified :
 * @Version : 1.0
 */
@Slf4j
public class DynamicValueHelper {

    /**
     * 计算Field字段的@DynamicValue 注解出来
     * @param bean
     * @param field
     * @return
     */
    public static DynamicValueBean computeDynamicFieldAnnotation(Object bean, Field field) {

        // 判断是否直接标注@DynamicValue 注解,还是@DynamicSwitch 注解,还是通过在Class类上标注的@DynamicValue

        DynamicValueBean dynamicValueBean = new DynamicValueBean();
        // 获取Field字段上的@DynamicValue注解
        DynamicValue dynamicValue = AnnotationUtils.getAnnotation(field, DynamicValue.class);

        if (Objects.nonNull(dynamicValue)) {
            // 获取Key: 因为使用了@AliasFor 注解和 key() 属性是相通的
            String key = (String) AnnotationUtils.getValue(dynamicValue);
            if (StringUtils.isBlank(key)) {
                // key 是默认值或者空的, 采用字段的全限定名称
                String clazzName = field.getDeclaringClass().getName();
                String fieldName = field.getName();
                key = clazzName + TransformationConstants.FIELD_LOCATION_SEPARATOR + fieldName;
            }

            // 获取默认值: 如果注解没有配置默认值,那么设置
            String value = dynamicValue.defaultValue();
            if (Objects.isNull(value) || value.length() == 0) {
                // 如果是默认值"", 则需要进行判断

                try {
                    // 获取field字段声明的时候的初始值
                    field.setAccessible(true);
                    Object initValue = field.get(bean);
                    if (Objects.nonNull(initValue)) {
                        // 非空,进行赋值
                        value = ReflectUtil.valueToAdaptiveString(initValue);
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            // 获取值类型的Class
            Class<?> valueClass = dynamicValue.valueClass();
            if (Objects.isNull(valueClass) || ReflectUtil.isVoidType(valueClass)) {
                // 如果没有指定类型或者类型为void -> 获取Field字段类型进行赋值
                valueClass = field.getType();
            }

            // 获取规则表达式
            String expression = dynamicValue.expression();
            if (StringUtils.isNotBlank(expression)) {
                String elType = dynamicValue.elType();
                dynamicValueBean.setExpression(expression).setElType(elType);
            }

            // 构造DynamicValueBean 对象
            dynamicValueBean.setKey(key).setValue(value).setDefaultValue(value).setValueClass(valueClass);
            return dynamicValueBean;
        }

        // @DynamicValue 注解为空,判断是否为添加了@DynamicSwitch 注解
        DynamicSwitch dynamicSwitch = AnnotationUtils.getAnnotation(field, DynamicSwitch.class);
        if (Objects.nonNull(dynamicSwitch)) {
            // 获取Key: 因为使用了@AliasFor 注解和 key() 属性是相通的
            String key = (String) AnnotationUtils.getValue(dynamicSwitch);
            if (StringUtils.isBlank(key)) {
                // key 是默认值或者空的, 采用字段的全限定名称
                String clazzName = field.getDeclaringClass().getName();
                String fieldName = field.getName();
                key = clazzName + TransformationConstants.FIELD_LOCATION_SEPARATOR + fieldName;
            }

            // 获取默认值: 如果注解没有配置默认值,那么设置
            boolean value = dynamicSwitch.defaultValue();
            if (BooleanUtils.isFalse(value)) {
                // 如果是默认值false, 则需要进行判断
                try {
                    // 获取field字段声明的时候的初始值
                    field.setAccessible(true);
                    boolean initValue = field.getBoolean(bean);
                    if (Objects.nonNull(initValue)) {
                        // 非空,进行赋值
                        value = initValue;
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

            // 获取值类型的Class
            Class<?> valueClass = dynamicSwitch.valueClass();
            if (Objects.isNull(valueClass) || ReflectUtil.isVoidType(valueClass)) {
                // 如果没有指定类型或者类型为void -> 获取Field字段类型进行赋值
                valueClass = field.getType();
            }

            // 获取规则表达式
            String expression = dynamicSwitch.expression();
            if (StringUtils.isNotBlank(expression)) {
                String elType = dynamicSwitch.elType();
                dynamicValueBean.setExpression(expression).setElType(elType);
            }

            // 构造DynamicValueBean 对象
            String initValue = Boolean.valueOf(value).toString();
            dynamicValueBean.setKey(key).setValue(initValue)
                    .setDefaultValue(initValue)
                    .setValueClass(valueClass);

            return dynamicValueBean;
        }

        // 如果这些注解都没有,需要判断类上是否添加了@DynamicValue 注解来进行设置
        dynamicValue = AnnotationUtils.findAnnotation(bean.getClass(), DynamicValue.class);
        if (Objects.nonNull(dynamicValue)) {
            // 此处是添加在类上的动态注解
            // TODO 后期考虑添加缓存存储这些注解信息,与对象,field,method的映射信息

            // key 为field 的全限定名称,或者如果类上的DynamicValue 注解指定了key 则采用key.fieldName
            String key = dynamicValue.key();
            if (StringUtils.isEmpty(key) || key.length() == 0) {
                key = bean.getClass().getName();
            }
            key = key.concat(TransformationConstants.FIELD_LOCATION_SEPARATOR).concat(field.getName());

            // 默认值:field 字段的显示初始值
            Object initValue = null;
            Class<?> initValueClass = null;
            try {
                initValue = field.get(bean);
                initValueClass = initValue.getClass();

                // 设置
                dynamicValueBean.setValue(initValue.toString())
                        .setDefaultValue(initValue.toString())
                        .setValueClass(initValueClass);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

            // TODO 考虑String 类型更改为Object类型
            // TODO 以后考虑字段上的@Value注解内部的 spEl 表达式
            dynamicValueBean.setKey(key);
            return dynamicValueBean;
        }

        // 能够寻找的地方都进行了查找,还是不能构建出来,返回null, 外面进行判断
        return null;
    }


    /**
     * 给字段赋值
     * @param field 字段
     * @param value 值
     * @param clazz 值类型
     */
    public static void assignField(Field field, String value, Class<?> clazz) {

        Class<?> type = field.getType();
    }


    /**
     * 计算出能够赋值的适配的类,如果不能转换为适配的类,将抛出异常
     * @param bean
     * @param field 字段属性声明类型
     * @param value 原始数值
     * @param valueClass
     * @return
     */
    public static Object computeAdaptiveDynamicValue(Object bean, Field field, Object value, Class<?> valueClass) {

        // 判断是否可以分配
        boolean assignable = ReflectUtil.isAssignable(field, field.getType(), value, valueClass);
        if (BooleanUtils.isFalse(assignable)) {
             // 不能赋值
            log.error("field:{}-class:{} can not assigned by value:{}-class{}", field, field.getClass(), value, valueClass);
            throw new ClassCastException("field:" + field + "-class:"+ field.getClass() + ", can not assigned by value:"+ value + "-class:" + valueClass);
        }

        Class<?> fieldType = field.getType();
        // // 判断 valueClass 是否可以直接分配给 fieldClass
        if (ClassUtils.isAssignable(valueClass, fieldType)) {
            // 可以直接分配,返回值
            return value;
        }

        // 是否基本类型
        if (ReflectUtil.isBaseType(fieldType)) {
            // 基本类型:number,void, boolean, char, string
            if (ReflectUtil.isNumberType(fieldType)) {
                // 如果valueClass 也是number类型那么在前面 ClassUtils.isAssignable() 则会判断成功已经返回了
                // 此时value 可能为Number中非基本类型及其包装类,或者为String类
                if (valueClass.isPrimitive()) {
                    // 如果是基本类型需要转换为包装类型
                    valueClass = ClassUtils.wrapperToPrimitive(valueClass);
                }

                // 判断是否是数值类型
                if (ReflectUtil.isNumberType(valueClass)) {
                    return NumberUtils.createNumber(value.toString());
                } else if (ReflectUtil.isStringType(valueClass)) {
                    // 如果是String 直接尝试转换为Number
                    return NumberUtils.createNumber(value.toString());
                }

                // 如果既不是基本数值类型也不是其包装类型,也不是字符串那么无法转换,抛出异常
                throw new ClassCastException("value:" + value + ", class is " + valueClass + ", can not convert to field class:" + fieldType);
            } else if (ReflectUtil.isBooleanType(fieldType)) {
                // boolean 类型: 直接判断是否可以转为Boolean
                return BooleanUtils.toBooleanObject(value.toString());
            } else if (ReflectUtil.isCharType(fieldType)) {
                // char 类型,尝试直接转换为一个char
                if (ReflectUtil.isCharType(valueClass)) {
                    // 无需转换直接返回
                    return value;
                }
                // 转换成为char
                return CharUtils.toCharacterObject(value.toString());
            } else if (ReflectUtil.isStringType(valueClass)) {
                return String.valueOf(value);
            }
        }
        // 是否集合类型
        else if (ReflectUtil.isCollectionType(fieldType)) {
            Class<?> genericType = ReflectUtil.getGenericType(field);
            // 如果是集合类型可以判断value 是否集合,还是componentClass ,还是String 类型来进行单独值转换
            if (ReflectUtil.isCollectionType(valueClass)) {
                return CollectionConverter.convertCollection(fieldType, (Collection) value, genericType);
            } else if (genericType.isAssignableFrom(valueClass)) {
                // 如果不是集合,判断泛型类型是否可以被value类型赋值
                return value;
            } else if (ReflectUtil.isPrimitiveOrWrapperType(valueClass)) {
                // 如果是基本数据类型
                return genericType.cast(value);
            } else if (ReflectUtil.isStringType(valueClass)) {
                // String 类型的需要将其转换为[], 或者{} 格式
                String[] valueArray = StringConverter.convertStringToArray(String.valueOf(value));
                // 还需要判断元素能不能转换为genericType
                Gson gson = new Gson();
                ArrayList<Object> res = Lists.newArrayList();
                for (String v : valueArray) {
                    res.add(gson.fromJson(v, genericType));
                }
                return res;
            } else {
                throw new ClassCastException("value:" + value + ", class is " + valueClass + ", can not convert to field class:" + fieldType);
            }
        }
        // 是数组类型
        else if (ReflectUtil.isArrayType(fieldType)) {

            // 获取componentType
            Class<?> componentType = fieldType.getComponentType();
            // 如果value 也是Array类型
            if (ReflectUtil.isArrayType(valueClass)) {
                Class<?> valueComponentType = valueClass.getComponentType();
                if (ClassUtils.isAssignable(valueComponentType, componentType)) {
                    // 可以直接赋值
                    return value;
                } else {
                    // 类型不能直接赋值,是否可以通过转换
                    Gson gson = new Gson();
                    gson.fromJson(String.valueOf(value), fieldType);
                }
            } else if (ReflectUtil.isPrimitiveOrWrapperType(valueClass)) {
                if (ClassUtils.isAssignable(valueClass, componentType)) {
                    return value;
                }
                throw new ClassCastException("value:" + value + ", class is " + valueClass + ", can not convert to field class:" + fieldType);
            } else if (ReflectUtil.isStringType(valueClass)) {

                // 转换为数组分割
                String[] vArray = StringConverter.convertStringToArray((String) value);

                // 创建ComponentType 类型数组
                Gson gson = new Gson();
                Object componentArray = Array.newInstance(componentType, vArray.length);

                // 添加转换后的元素
                for (int i = 0; i < vArray.length; i++) {

                    // 转换元素为指定类型
                    Object o = gson.fromJson(vArray[i], componentType);
                    // 如果可以成功转换,设置,没有抛出异常则说明能够构造出适应的数据结构
                    Array.set(componentArray, i, o);
                }

                // 没有抛出异常
                return componentArray;
            } else if (ReflectUtil.isCollectionType(valueClass)) {
                // 集合类型: 直接判断是否可以转换
                Type valueGenericType = ReflectUtil.getGenericType(valueClass);
                if (ClassUtils.isAssignable((Class<?>) valueGenericType, fieldType)) {
                    return ((Collection) value).toArray();
                }
            }
        }
        // 是否Map 类型
        else if (ReflectUtil.isMapType(fieldType)) {

        }
        // 是否对象类型
        else {
            Gson gson = new Gson();
            return gson.fromJson((String) value, fieldType);
        }


        // 战时没有匹配的类型
        throw new ClassCastException("value:" + value + ", class is " + valueClass + ", can not convert to field class:" + fieldType);
    }
}

ReflectUtil 工具类:

package com.hk.transformation.core.reflect.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;

/**
 * @author : HK意境
 * @ClassName : ReflectUtil
 * @date : 2023/8/19 10:27
 * @description :
 * @Todo :
 * @Bug :
 * @Modified :
 * @Version : 1.0
 */
public class ReflectUtil {


    /**
     * 判断是否可以赋值
     * @param field 字段
     * @param value
     * @param fieldType 字段属性声明类型
     * @param valueType
     * @return
     */
    public static boolean isAssignable(Field field, Class<?> fieldType, Object value, Class<?> valueType) {

        // 如果是 void.class 不能赋值
        if (isVoidType(fieldType) || isVoidType(valueType)) {
            return false;
        }

        // 如果设置的类型都是相同的那么即可直接赋值
        if (fieldType.isAssignableFrom(valueType)) {
            // 可赋值的
            return true;
        }

        // 判断field 是否基本类型
        if (isBaseType(fieldType)) {

            if (isStringType(fieldType)) {
                if (isStringType(valueType)) {
                    return true;
                }
                // 不是String类型但是如果是基本类型,那么是可以转换为String的,但如果是其他对象类型则不行
                return isBaseType(valueType);
            } else if (isNumberType(fieldType)) {
                // 判断是否数值类型
                if (isNumberType(valueType)) {
                    return true;
                } else if (String.class.equals(valueType)) {
                    // 是字符串,判断是否可以通过转换成为数值
                    return NumberUtils.isCreatable(String.valueOf(value));
                }
            } else if (isCharType(fieldType)) {
                // 是否Char类型
                if (isCharType(valueType)) {
                    return true;
                } else if (String.class.equals(valueType)) {
                    return isCharValue((String) value);
                }
            } else if (isBooleanType(fieldType)) {
                // 是否Boolean类型
                if (isCharType(valueType)) {
                    return true;
                } else if (String.class.equals(valueType)) {
                    return isBooleanValue((String) value);
                }
            }
        } else if (fieldType.isArray()) {
            // 是否数组类型

            // 获取数组成员类型
            Class<?> fieldComponentType = fieldType.getComponentType();
            // 需要判断valueType是否也为数组
            if (valueType.isArray()) {
                // 如果也是数组需要判断成员是否能够赋值
                Class<?> valueComponentType = valueType.getComponentType();
                // 如果值类型也是数组对象,其实可以直接判断两个成员类型是否可以赋值
                return fieldComponentType.isAssignableFrom(valueComponentType);
            } else {

                // valueType 值类型不是数组,但是可能为单个元素值,也可能为String
                // 判断valueType 和 fieldComponentType 的关系。
                if (fieldComponentType.isAssignableFrom(valueType)) {
                    // 单个元素可以赋值
                    return true;
                }

                // 不是能够直接赋值的,需要判断是否可以转换
                if (isBaseType(fieldComponentType) && isBaseType(valueType)) {
                    return true;
                }

                return false;
            }
        } else if (isCollectionType(fieldType)) {

            // 判断valueType 类型
            Class<?> genericType = getGenericType(field);
            if (isCollectionType(valueType)) {
                // 是否可以赋值或进行转换
                return true;
            } else if (isStringType(valueType)) {
                // 字符串类型
                return true;
            } else if (isArrayType(valueType)){
                // 非集合,非字符串,尝试是否数组类型

                // 获取集合元素类型
                Class<?> componentType = valueType.getComponentType();
                if (genericType.isAssignableFrom(componentType)) {

                    // 能够直接赋值
                    return true;
                } else if (isBaseType(genericType) && isBaseType(componentType)){

                    // 不能直接赋值,是否可以通过转换
                    return true;
                } else if (isStringType(componentType)) {
                    return true;
                }
            }

            return false;
        } else {
            // 是否对象类型
            return isStringType(valueType);
        }

        return false;
    }

    /**
     * 是否基本类型:原始类型 + 包装类 + 字符串类型
     * @param targetClazz
     * @return
     */
    public static boolean isBaseType(Class<?> targetClazz) {

        return isNumberType(targetClazz) || isCharType(targetClazz) || isBooleanType(targetClazz) || isStringType(targetClazz);
    }

    /**
     * 是否基本类型及其包装类,不包括String
     * @param targetClazz
     * @return
     */
    public static boolean isPrimitiveOrWrapperType(Class<?> targetClazz) {

        return isNumberType(targetClazz) || isCharType(targetClazz) || isBooleanType(targetClazz);
    }


    /**
     * 是否数组类型
     * @param targetClazz
     * @return
     */
    public static boolean isArrayType(Class<?> targetClazz) {

        return targetClazz.isArray();
    }


    /**
     * 是否集合类型
     * @param targetClazz
     * @return
     */
    public static boolean isCollectionType(Class<?> targetClazz) {
        return Collection.class.isAssignableFrom(targetClazz);
    }


    /**
     * 是否是Map 类型
     * @param targetClazz
     * @return
     */
    public static boolean isMapType(Class<?> targetClazz) {
        return Map.class.isAssignableFrom(targetClazz);
    }

    /**
     * 判断是否数值类型
     * @param targetClazz java.lang.reflect.Field 的数据类型 clazz。 getType 方法获取
     * @return boolean 是否是Number类型
     */
    public static boolean isNumberType(Class<?> targetClazz) {

        // 判断包装类
        if (Number.class.isAssignableFrom(targetClazz)) {
            // 基本类型包装类,BigDecimal, BigInteger, 原子类
            return true;
        }

        // 判断原始类,过滤掉特殊的基本类型
        if (targetClazz == boolean.class || targetClazz == char.class || targetClazz == void.class) {
            return false;
        }

        // 基本类型 + boolean + char + void
        return targetClazz.isPrimitive();
    }


    /**
     * 判断是否Boolean类型
     * @param targetClazz 目标类
     * @return
     */
    public static boolean isBooleanType(Class<?> targetClazz) {

        // Boolean 类型就两种状态基本类和包装类
        return Boolean.class.isAssignableFrom(targetClazz);
    }


    /**
     * 判断是否Boolean类型
     * @param targetClazz 目标类
     * @return
     */
    public static boolean isCharType(Class<?> targetClazz) {

        // Boolean 类型就两种状态基本类和包装类
        return Character.class.isAssignableFrom(targetClazz);
    }

    /**
     * 判断是否String类型
     * @param targetClazz
     * @return
     */
    public static boolean isStringType(Class<?> targetClazz) {

        return String.class.equals(targetClazz);
    }


    /**
     * 判断是否void类型
     * @param targetClazz
     * @return
     */
    public static boolean isVoidType(Class<?> targetClazz) {

        return Void.class.equals(targetClazz) || void.class.equals(targetClazz);
    }

    /**
     * 判断一个String是否可以转换为Boolean值
     * @param value
     * @return
     */
    public static boolean isBooleanValue(String value) {
        return "true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value);
    }


    /**
     * 判断一个String是否可以转换为Char
     * @param str
     * @return
     */
    public static boolean isCharValue(String str) {
        return StringUtils.isEmpty(str) || str.length() == 1;
    }


    /**
     * 获取泛型的类型
     * @param field
     * @return
     */
    public static Class<?> getGenericType(Field field) {

        Type listFieldType = field.getGenericType();
        if (listFieldType instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) listFieldType).getActualTypeArguments();
            if (actualTypeArguments.length > 0) {
                // 显示指定了泛型类型
                Type genericType = actualTypeArguments[0];
                return getTypeClass(genericType);
            } else {
                // 没有指定泛型类型,返回 Object
                return Object.class;
            }
        } else {
            // 没有指定泛型
            return field.getDeclaringClass();
        }
    }


    /**
     * 获取一个类声明的泛型参数
     * @param clazz
     * @return
     */
    public static Type getGenericType(Class<?> clazz) {
        Type type = clazz.getGenericSuperclass();
        if (type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type[] typeArguments = parameterizedType.getActualTypeArguments();
            if (typeArguments.length > 0) {
                return typeArguments[0];
            }
        }
        return Object.class;
    }


    public static Class<?> getTypeClass(Type type) {
        if (type instanceof Class) {
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            return (Class<?>) ((ParameterizedType) type).getRawType();
        } else {
            throw new IllegalArgumentException("Unsupported Type: " + type);
        }
    }


    /**
     * 将Value转换为适合的String:基本类型直接of(), 数组类型转换为[e1,e2,e3,e4], 集合类型转换为{1,2,3,4},对象类型转换为JSON对象,Map 类型转换为{key:value,key:value,key:value}
     * @param value
     * @return
     */
    public static String valueToAdaptiveString(Object value) {


        return "";
    }
}

求助

各位大佬看了我的代码什么感想,想要求助还有什么更加优雅和好的方法或者开源工具类方案的。迫切需要解决这个核心问题。