复制对象非空值到另一个对象中

作用

平常修改某些信息的时候需要检查此值是否为空,不为空的话才对其赋值修改,但当属性过多时,这个操作就会变得很烦。此工具类作用就是简化其繁琐的操作。

思路

  1. 将from的属性遍历,先判断其是否允许复制,然后判断其值为不为空
  2. 将允许复制的且值不为空的挑出来,将其值复制到to对象

源码

public class CopyUtils {
    public static void copyObjectNotNullSameClass(Object to, Object from, String[] exclude) {
        copyObjectNotNullSameClass(to, from, exclude, false);
    }

    /**
     * 复制对象内的所有非空值,到另一个对象的相同属性名中(同一类的)
     * 思路:
     * 1. 将from的属性遍历,先判断其是否允许复制,然后判断其值为不为空
     * 2. 将允许复制的且值不为空的挑出来,将其值复制到to对象
     *
     * @param to      值 复制 给 此类
     * @param from    值 来自 此类
     * @param exclude 排除一些特殊参数,不复制
     */
    public static void copyObjectNotNullSameClass(Object to, Object from, String[] exclude, boolean hasSuper) {
        String name = '';
        try {
            //获取字节码文件
            Class<?> fromClass = from.getClass();
            Class<?> toClass = to.getClass();

            //获取其所有属性
            List<Field> fromDeclaredFields = null;
            List<Field> toDeclaredFields = null;
            if (hasSuper) {
                fromDeclaredFields = getObjectAllFields(fromClass);
                toDeclaredFields = getObjectAllFields(toClass);
            } else {
                fromDeclaredFields = Arrays.asList(fromClass.getDeclaredFields());
            }
            //遍历属性
            for (Field fromField : fromDeclaredFields) {
                fromField.setAccessible(true);//赋予权限
                name = fromField.getName();//获取其属性名
                Object value = fromField.get(from);//从from对象获取其属性值
                if (value == null) {
                    continue;
                }
                Field toField = null;//从to对象获取值
                try {
                    if (hasSuper) {
                        toField = getObjectFieldByName(name, toDeclaredFields);
                    } else {
                        toField = toClass.getDeclaredField(name);
                    }
                } catch (NoSuchFieldException e) {
//                        ErrorUtil.printWarring(e, '找不到此属性 ' + name);
                    continue;
                }
                if (isAll(name, exclude)) {//判断其属性名是否允许复制,且其属性值是否为空
                    toField.setAccessible(true);
                    toField.set(to, value);//将from对象的值复制给to对象
                }
            }
        } catch (IllegalAccessException e) {
            ErrorUtil.printError(e, name + ' 获取值发生错误');
        }
    }

    public static void copyObjectNotNullNotSameClass(Object to, Object from, String[] exclude) {
        copyObjectNotNullNotSameClass(to, from, exclude, false);
    }

    /**
     * 复制对象内的非空值,到另一个对象的相同属性名中(非同一类的)
     * 思路:
     * 1. 将from的属性遍历,先判断其是否允许复制,然后判断其值为不为空
     * 2. 将允许复制的且值不为空的挑出来,将其值复制到to对象
     *
     * @param to      值 复制 给 此类
     * @param from    值 来自 此类
     * @param exclude 排除一些特殊参数,不复制
     */
    public static void copyObjectNotNullNotSameClass(Object to, Object from, String[] exclude, boolean hasSuper) {
        String name = '';
        try {
            //获取字节码文件
            Class<?> fromClass = from.getClass();
            Class<?> toClass = to.getClass();

            //获取其所有属性
            List<Field> fromDeclaredFields = null;
            List<Field> toDeclaredFields = null;
            if (hasSuper) {
                fromDeclaredFields = getObjectAllFields(fromClass);
                toDeclaredFields = getObjectAllFields(toClass);
            } else {
                fromDeclaredFields = Arrays.asList(fromClass.getDeclaredFields());
            }

            //遍历属性
            for (Field fromField : fromDeclaredFields) {
                fromField.setAccessible(true);//赋予权限
                name = fromField.getName();//获取其属性名
                Object value = fromField.get(from);//从from对象获取其属性值
                if (isAll(name, exclude) && value != null) {//判断其属性名是否允许复制,且其属性值是否为空
                    Field toField = null;//从to对象获取值
                    try {
                        if (hasSuper) {
                            toField = getObjectFieldByName(name, toDeclaredFields);
                        } else {
                            toField = toClass.getDeclaredField(name);
                        }
                    } catch (NoSuchFieldException e) {
//                        ErrorUtil.printWarring(e, '找不到此属性 ' + name);
                        continue;
                    }
                    toField.setAccessible(true);
                    try {
                        toField.set(to, value);//将from对象的值复制给to对象
                    } catch (Exception e) {
                        ErrorUtil.printError(e, name + ' 属性的类型不匹配');
                    }
                }
            }
        } catch (IllegalAccessException e) {
            ErrorUtil.printError(e, name + ' 获取值发生错误');
        }
    }

    /**
     * 找到此属性名的属性,找不到报错
     *
     * @param name
     * @param declaredFields
     * @return
     * @throws NoSuchFieldException
     */
    private static Field getObjectFieldByName(String name, List<Field> declaredFields) throws NoSuchFieldException {
        for (Field declaredField : declaredFields) {
            if (declaredField.getName().equals(name)) {
                return declaredField;
            }
        }
        throw new NoSuchFieldException();
    }

    /**
     * 获取其所有属性及其父类的属性
     *
     * @param clazz
     * @return
     */
    private static List<Field> getObjectAllFields(Class<?> clazz) {
        ArrayList<Field> fields = new ArrayList<>();
        //获取其属性
        Field[] declaredFields = clazz.getDeclaredFields();
        fields.addAll(Arrays.stream(declaredFields).collect(Collectors.toList()));
        //获取其父类属性
        Class<?> superclass = clazz.getSuperclass();
        if (superclass != null) {
            fields.addAll(getObjectAllFields(superclass));
        }
        return fields;
    }

    /**
     * 此值是否排除
     *
     * @param key
     * @param exclude
     * @return
     */
    private static boolean isAll(String key, String[] exclude) {
        if (exclude != null && exclude.length > 0) {
            for (String s : exclude) {
                if (s.equals(key)) {
                    return false;
                }
            }
        }
        return true;
    }
}

注意

集合等特殊的属性,会把非null的空集合覆盖,操作要小心。

结束

如有问题,可以联系我

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值