Java将一个对象中非空的字段覆盖到另一个对象中

Posted *King*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java将一个对象中非空的字段覆盖到另一个对象中相关的知识,希望对你有一定的参考价值。

前缀:

在开发中我们现在将一个对象中的非空字段覆盖到另一个对象中,虽然BeanUtils.copyProperties()和PropertyUtils.copyProperties()方法也可以实现,但是它是将整个对象完全复制到另一个对象里,与我们预期的不一样,所以这里可以参考一下如下的代码:

具体方法:

/**
     * 功能说明: 只复制source对象的非空属性到target对象上
     * @param source
     * @param target
     * @throws BeansException
     */
    public static void copyNoNullProperties(Object source, Object target) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> actualEditable = target.getClass();
        PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
        for (PropertyDescriptor targetPd : targetPds) {
            if (targetPd.getWriteMethod() != null) {
                PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null && sourcePd.getReadMethod() != null) {
                    try {
                        Method readMethod = sourcePd.getReadMethod();
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                            readMethod.setAccessible(true);
                        }
                        Object value = readMethod.invoke(source);
                        // 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等
                        if (value != null) {
                            Method writeMethod = targetPd.getWriteMethod();
                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                writeMethod.setAccessible(true);
                            }
                            writeMethod.invoke(target, value);
                        }
                    } catch (Throwable ex) {
                        throw new FatalBeanException("Could not copy properties from source to target", ex);
                    }
                }
            }
        }
    }

实践:

User1

public class User1 {
    private String name;
    private String sex;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User1{" +
                "name='" + name + '\\'' +
                ", sex='" + sex + '\\'' +
                ", age=" + age +
                '}';
    }
}

User2

public class User2 {

    private String name;
    private String sex;
    private Integer age;
    private String remark;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "User2{" +
                "name='" + name + '\\'' +
                ", sex='" + sex + '\\'' +
                ", age=" + age +
                ", remark='" + remark + '\\'' +
                '}';
    }
}

Test

import cn.hutool.core.lang.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Test {

    public static void main(String[] args) {
        User1 user1 = new User1();
        user1.setName("小明");

        User2 user2 = new User2();
        user2.setName("小红");
        user2.setAge(18);
        user2.setRemark("12456");

        copyNoNullProperties(user1,user2);
        System.out.println(user2.toString());
    }

    /**
     * 功能说明: 只复制source对象的非空属性到target对象上
     * @param source
     * @param target
     * @throws BeansException
     */
    public static void copyNoNullProperties(Object source, Object target) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        Class<?> actualEditable = target.getClass();
        PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
        for (PropertyDescriptor targetPd : targetPds) {
            if (targetPd.getWriteMethod() != null) {
                PropertyDescriptor sourcePd = BeanUtils.getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null && sourcePd.getReadMethod() != null) {
                    try {
                        Method readMethod = sourcePd.getReadMethod();
                        if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                            readMethod.setAccessible(true);
                        }
                        Object value = readMethod.invoke(source);
                        // 这里判断以下value是否为空 当然这里也能进行一些特殊要求的处理 例如绑定时格式转换等等
                        if (value != null) {
                            Method writeMethod = targetPd.getWriteMethod();
                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                writeMethod.setAccessible(true);
                            }
                            writeMethod.invoke(target, value);
                        }
                    } catch (Throwable ex) {
                        throw new FatalBeanException("Could not copy properties from source to target", ex);
                    }
                }
            }
        }
    }
}

测试结果:

以上是关于Java将一个对象中非空的字段覆盖到另一个对象中的主要内容,如果未能解决你的问题,请参考以下文章

为啥打字稿允许我覆盖一个空的状态对象?

XStream将java对象解析为xml字符串时,过滤掉节点值为空的节点

将数据库对象复制到另一个-django

从 json 动态创建的 Javascript 表单输入,需要将对象映射到另一个对象的正确字段并保存

Java。如何将一个LinkedList里的元素全部复制到另一LinkedList容器里?

navicat premium如何将一个字段批量覆盖到另一个字段