工具类之对象转换工具POJO转换成目标类型(反射应用)

public class PojoConvertUtils {
    private static Logger logger = LoggerFactory.getLogger(PojoConvertUtils.class);
    /**
     * 变量缓存
     */
    private static final Map<String, Map<String, Field>> CACHEFIELDS = new ConcurrentHashMap<>();
    /**
     * 基本类型
     */
    private static final Set<Class> BASICCLASS = new HashSet<>();

    /**
     * 泛型
     */
    private static final Integer SECOND_T = 1<<1;

    /**
     * HashMap初始值大写16个元素
     */
    private static final Integer DEFAULT_SIZE = 1<<4;

    static {
        BASICCLASS.add(Integer.class);
        BASICCLASS.add(Character.class);
        BASICCLASS.add(Byte.class);
        BASICCLASS.add(Float.class);
        BASICCLASS.add(Double.class);
        BASICCLASS.add(Boolean.class);
        BASICCLASS.add(Long.class);
        BASICCLASS.add(Short.class);
        BASICCLASS.add(String.class);
        BASICCLASS.add(BigDecimal.class);
    }

    /**
     * 将具有相同属性的类型进行转换
     *
     * @param orig
     * @param <T>
     * @return
     */
    public static <T> T convertPojo(Object orig, Class<T> targetClass) {
        try {
            if(orig==null) {
                return null;
            }
            T target = targetClass.newInstance();
            /** 获取源对象的所有变量 */
            List<Field> fields = new ArrayList<>() ;
            Class tempClass = orig.getClass();
            while (tempClass != null) {
                //当父类为null的时候说明到达了最上层的父类(Object类).
                fields.addAll(Arrays.asList(tempClass .getDeclaredFields()));
                //得到父类,然后赋给自己
                tempClass = tempClass.getSuperclass();
            }
            //Field[] fields = orig.getClass().getDeclaredFields();
            for (Field field : fields) {
                if (isStatic(field)) {
                    continue;
                }
                /** 获取目标方法 */
                Field targetField = getTargetField(targetClass, field.getName());
                if (targetField == null) {
                    continue;
                }
                Object value = getFiledValue(field, orig);
                if (value == null) {
                    continue;
                }
                Class type1 = field.getType();
                Class type2 = targetField.getType();
                //两个类型是否相同
                boolean sameType = type1.equals(type2);
                if (isBasicType(type1)) {
                    if (sameType) {
                        setFieldValue(targetField, target, value);
                    }
                } else if (value instanceof Map && Map.class.isAssignableFrom(type2)) {
                    //对map
                    setMap((Map) value, field, targetField, target);
                } else if (value instanceof Set && Set.class.isAssignableFrom(type2)) {
                    //对set
                    setCollection((Collection) value, field, targetField, target);
                } else if (value instanceof List && List.class.isAssignableFrom(type2)) {
                    //对list
                    setCollection((Collection) value, field, targetField, target);
                } else if (value instanceof Enum && Enum.class.isAssignableFrom(type2)) {
                    //对enum
                    setEnum((Enum) value, field, targetField, target);
                } else if (value instanceof Date && Date.class.isAssignableFrom(type2)) {
                    //对日期类型,不处理如joda包之类的扩展时间,不处理calendar
                    setDate((Date) value, targetField, type2, target, sameType);
                }
            }
            return target;
        } catch (Throwable t) {
            logger.error("转换失败:" + t.getMessage());
            throw new RuntimeException(t.getMessage());
        }
    }

    /**
     * 获取字段值
     *
     * @param field
     * @param obj
     * @return
     */
    private static Object getFiledValue(Field field, Object obj) throws IllegalAccessException {
        //获取原有的访问权限
        boolean access = field.isAccessible();
        try {
            //设置可访问的权限
            field.setAccessible(true);
            return field.get(obj);
        } finally {
            //恢复访问权限
            field.setAccessible(access);
        }
    }

    /**
     * 设置方法值
     *
     * @param field
     * @param obj
     * @param value
     * @throws IllegalAccessException
     */
    private static void setFieldValue(Field field, Object obj, Object value) throws IllegalAccessException {
        //获取原有的访问权限
        boolean access = field.isAccessible();
        try {
            //设置可访问的权限
            field.setAccessible(true);
            field.set(obj, value);
        } finally {
            //恢复访问权限
            field.setAccessible(access);
        }
    }

    /**
     * 转换list
     *
     * @param orig
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T> List<T> convertPojos(List orig, Class<T> targetClass) {
        List<T> list = new ArrayList<>(orig.size());
        for (Object object : orig) {
            list.add(convertPojo(object, targetClass));
        }
        return list;
    }

    /**
     * 设置Map
     *
     * @param value
     * @param origField
     * @param targetField
     * @param targetObject
     * @param <T>
     */
    private static <T> void setMap(Map value, Field origField, Field targetField, T targetObject) throws IllegalAccessException, InstantiationException {
        Type origType = origField.getGenericType();
        Type targetType = targetField.getGenericType();
        if (origType instanceof ParameterizedType && targetType instanceof ParameterizedType) {
            //泛型类型
            ParameterizedType origParameterizedType = (ParameterizedType) origType;
            Type[] origTypes = origParameterizedType.getActualTypeArguments();
            ParameterizedType targetParameterizedType = (ParameterizedType) targetType;
            Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
            if (origTypes != null && origTypes.length == SECOND_T && targetTypes != null && targetTypes.length == SECOND_T) {
                //正常泛型,查看第二个泛型是否不为基本类型
                Class clazz = (Class) origTypes[1];
                if (!isBasicType(clazz) && !clazz.equals(targetTypes[1])) {
                    //如果不是基本类型并且泛型不一致,则需要继续转换
                    Set<Map.Entry> entries = value.entrySet();
                    Map targetMap = value.getClass().newInstance();
                    for (Map.Entry entry : entries) {
                        targetMap.put(entry.getKey(), convertPojo(entry.getValue(), (Class) targetTypes[1]));
                    }
                    setFieldValue(targetField, targetObject, targetMap);
                    return;
                }
            }
        }
        setFieldValue(targetField, targetObject, value);
    }

    /**
     * 设置集合
     *
     * @param value
     * @param origField
     * @param targetField
     * @param targetObject
     * @param <T>
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    private static <T> void setCollection(Collection value, Field origField, Field targetField, T targetObject) throws IllegalAccessException, InstantiationException {
        Type origType = origField.getGenericType();
        Type targetType = targetField.getGenericType();
        if (origType instanceof ParameterizedType && targetType instanceof ParameterizedType) {
            //泛型类型
            ParameterizedType origParameterizedType = (ParameterizedType) origType;
            Type[] origTypes = origParameterizedType.getActualTypeArguments();
            ParameterizedType targetParameterizedType = (ParameterizedType) targetType;
            Type[] targetTypes = targetParameterizedType.getActualTypeArguments();
            if (origTypes != null && origTypes.length == 1 && targetTypes != null && targetTypes.length == 1) {
                //正常泛型,查看第二个泛型是否不为基本类型
                Class clazz = (Class) origTypes[0];
                if (!isBasicType(clazz) && !clazz.equals(targetTypes[0])) {
                    //如果不是基本类型并且泛型不一致,则需要继续转换
                    Collection collection = value.getClass().newInstance();
                    for (Object obj : value) {
                        collection.add(convertPojo(obj, (Class) targetTypes[0]));
                    }
                    setFieldValue(targetField, targetObject, collection);
                    return;
                }
            }
        }
        setFieldValue(targetField, targetObject, value);
    }

    /**
     * 设置枚举类型
     *
     * @param value
     * @param origField
     * @param targetField
     * @param targetObject
     * @param <T>
     */
    private static <T> void setEnum(Enum value, Field origField, Field targetField, T targetObject) throws Exception {
        if (origField.equals(targetField)) {
            setFieldValue(targetField, targetObject, value);
        } else {
            //枚举类型都具有一个static修饰的valueOf方法
            Method method = targetField.getType().getMethod("valueOf", String.class);
            setFieldValue(targetField, targetObject, method.invoke(null, value.toString()));
        }
    }

    /**
     * 设置日期类型
     *
     * @param value
     * @param targetField
     * @param targetFieldType
     * @param targetObject
     * @param <T>
     */
    private static <T> void setDate(Date value, Field targetField, Class targetFieldType, T targetObject, boolean sameType) throws IllegalAccessException {
        Date date = null;
        if (sameType) {
            date = value;
        } else if (targetFieldType.equals(java.sql.Date.class)) {
            date = new java.sql.Date(value.getTime());
        } else if (targetFieldType.equals(Date.class)) {
            date = new Date(value.getTime());
        } else if (targetFieldType.equals(java.sql.Timestamp.class)) {
            date = new java.sql.Timestamp(value.getTime());
        }
        setFieldValue(targetField, targetObject, date);
    }

    /**
     * 获取适配方法
     *
     * @param clazz
     * @param fieldName
     * @return
     */
    public static Field getTargetField(Class clazz, String fieldName) {
        String classKey = clazz.getName();
        Map<String, Field> fieldMap = CACHEFIELDS.get(classKey);
        if (fieldMap == null) {
            fieldMap = new HashMap<>(DEFAULT_SIZE);
            //Field[] fields = clazz.getDeclaredFields();
            /** 获取源对象的所有变量 */
            List<Field> fields = new ArrayList<>() ;
            Class tempClass = clazz;
            while (tempClass != null) {
                //当父类为null的时候说明到达了最上层的父类(Object类).
                fields.addAll(Arrays.asList(tempClass .getDeclaredFields()));
                //得到父类,然后赋给自己
                tempClass = tempClass.getSuperclass();
            }
            for (Field field : fields) {
                if (isStatic(field)) {
                    continue;
                }
                fieldMap.put(field.getName(), field);
            }
            CACHEFIELDS.put(classKey, fieldMap);
        }
        return fieldMap.get(fieldName);
    }

    /**
     * 确实是否为基础类型
     *
     * @param clazz
     * @return
     */
    public static boolean isBasicType(Class clazz) {
        return clazz.isPrimitive() || BASICCLASS.contains(clazz);
    }

    /**
     * 判断变量是否有静态修饰符static
     *
     * @param field
     * @return
     */
    public static boolean isStatic(Field field) {
        return (8 & field.getModifiers()) == 8;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值