千家信息网

java怎么复制非空对象属性值

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,小编给大家分享一下java怎么复制非空对象属性值,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!java 复制非空对象属性值很多时候,我们需要通过对象拷贝,比如说VO类与数据库实体be
千家信息网最后更新 2026年10月31日java怎么复制非空对象属性值

小编给大家分享一下java怎么复制非空对象属性值,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

java 复制非空对象属性值

很多时候,我们需要通过对象拷贝,比如说VO类与数据库实体bean类、更新时非空对象不更新,对同一对象不同数据分开存储等

用于对象拷贝,spring 和 Apache都提供了相应的工具类方法,BeanUtils.copyProperties

但是对于非空属性拷贝就需要自己处理了

在这里借用spring中org.springframework.beans.BeanUtils类提供的方法

copyProperties(Object source, Object target, String... ignoreProperties)

/**     * Copy the property values of the given source bean into the given target bean,     * ignoring the given "ignoreProperties".     * 

Note: The source and target classes do not have to match or even be derived * from each other, as long as the properties match. Any bean properties that the * source bean exposes but the target bean does not will silently be ignored. *

This is just a convenience method. For more complex transfer needs, * consider using a full BeanWrapper. * @param source the source bean * @param target the target bean * @param ignoreProperties array of property names to ignore * @throws BeansException if the copying failed * @see BeanWrapper */ public static void copyProperties(Object source, Object target, String... ignoreProperties) throws BeansException { copyProperties(source, target, null, ignoreProperties); /** * Copy the property values of the given source bean into the given target bean. *

Note: The source and target classes do not have to match or even be derived * from each other, as long as the properties match. Any bean properties that the * source bean exposes but the target bean does not will silently be ignored. * @param source the source bean * @param target the target bean * @param editable the class (or interface) to restrict property setting to * @param ignoreProperties array of property names to ignore * @throws BeansException if the copying failed * @see BeanWrapper */ private static void copyProperties(Object source, Object target, Class editable, String... ignoreProperties) throws BeansException { Assert.notNull(source, "Source must not be null"); Assert.notNull(target, "Target must not be null"); Class actualEditable = target.getClass(); if (editable != null) { if (!editable.isInstance(target)) { throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]"); } actualEditable = editable; } PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable); List ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null); for (PropertyDescriptor targetPd : targetPds) { Method writeMethod = targetPd.getWriteMethod(); if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) { PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName()); if (sourcePd != null) { Method readMethod = sourcePd.getReadMethod(); if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) { try { if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { readMethod.setAccessible(true); } Object value = readMethod.invoke(source); if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { writeMethod.setAccessible(true); } writeMethod.invoke(target, value); } catch (Throwable ex) { throw new FatalBeanException( "Could not copy property '" + targetPd.getName() + "' from source to target", ex); } } } } } }

然后封装一下得到以下方法

/**     * @author zml2015     * @Email zhengmingliang911@gmail.com     * @Time 2017年2月14日 下午5:14:25     * @Description 

获取到对象中属性为null的属性名

* @param source 要拷贝的对象 * @return */ public static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set emptyNames = new HashSet(); for (java.beans.PropertyDescriptor pd : pds) { Object srcValue = src.getPropertyValue(pd.getName()); if (srcValue == null) emptyNames.add(pd.getName()); } String[] result = new String[emptyNames.size()]; return emptyNames.toArray(result); } /** * @author zml2015 * @Email zhengmingliang911@gmail.com * @Time 2017年2月14日 下午5:15:30 * @Description

拷贝非空对象属性值

* @param source 源对象 * @param target 目标对象 */ public static void copyPropertiesIgnoreNull(Object source, Object target) { BeanUtils.copyProperties(source, target, getNullPropertyNames(source)); }

测试方法就不提供了,自行测试即可

如果项目中使用的框架有Hibernate的话,则可以通过在实体类上添加下面两条注解

@DynamicInsert(true)@DynamicUpdate(true)

如果想对该注解进一步了解的话,那么可以去官网看英文文档,文档解释的很清楚,在此不再赘述了

java对象属性复制的几种方式

1.使用java反射机制

获取对象的属性和get、set方法进行复制;

2.使用spring-beans5.0.8包中的BeanUtils类

import org.springframework.beans.BeanUtils;SourceObject sourceObject = new SourceObject();TargetObject targetObject = new TargetObject();BeanUtils.copyProperties(sourceObject, targetObject);

3.使用cglib3.2.8包中的net.sf.cglib.beans.BeanCopier类

import net.sf.cglib.beans.BeanCopier;import net.sf.cglib.core.Converter;SourceObject sourceObject = new SourceObject();TargetObject targetObject = new TargetObject();BeanCopier beanCopier = BeanCopier.create(SourceObject.class, TargetObject.class, true);--第三个参数表示是否使用转换器,false表示不使用,true表示使用Converter converter = new CopyConverter();--自定义转换器beanCopier.copy(sourceObject, targetObject, converter);

转换器(当源对象属性类型与目标对象属性类型不一致时,使用转换器):

import net.sf.cglib.core.Converter;import org.apache.commons.lang3.StringUtils;import java.math.BigDecimal;import java.util.Date;/** * Created by asus on 2019/7/12. */public class CopyConverter implements Converter {    @Override    public Object convert(Object value, Class target, Object context) {        {            String s = value.toString();            if (target.equals(int.class) || target.equals(Integer.class)) {                return Integer.parseInt(s);            }            if (target.equals(long.class) || target.equals(Long.class)) {                return Long.parseLong(s);            }            if (target.equals(float.class) || target.equals(Float.class)) {                return Float.parseFloat(s);            }            if (target.equals(double.class) || target.equals(Double.class)) {                return Double.parseDouble(s);            }            if(target.equals(Date.class)){                while(s.indexOf("-")>0){                    s = s.replace("-", "/");                }                return  new Date(s);            }            if(target.equals(BigDecimal.class)){                if(!StringUtils.isEmpty(s)&&!s.equals("NaN")){                    return  new BigDecimal(s);                }            }            return value ;        }    }}

4.使用spring-core5.0.8包

中的org.springframework.cglib.beans.BeanCopier类(用法与第三种一样)

import org.springframework.cglib.beans.BeanCopier;import org.springframework.cglib.core.Converter;SourceObject sourceObject = new SourceObject();TargetObject targetObject = new TargetObject();Converter converter = new SpringCopyConverter();BeanCopier beanCopier = BeanCopier.create(SourceObject.class, TargetObject.class, true);beanCopier.copy(sourceObject, targetObject, converter);

经过循环复制测试(源对象与目标对象各160个属性):

  • 第一种:Java反射通过判断属性类型,常用类型的属性值都能复制,但是不优化的前提下效率最慢;

  • 第二种:属性类型不同时无法复制,且效率相对较慢;

  • 第三种:耗时最少,不使用转换器时,属性类型不同时无法复制,使用转换器后,耗时会相对变长;

  • 第四种:与第三种相似,但是耗时相对较长;

看完了这篇文章,相信你对"java怎么复制非空对象属性值"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

对象 属性 类型 转换器 拷贝 方法 目标 测试 同时 实体 效率 数据 文档 注解 篇文章 反射 更新 不同 清楚 相似 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 亿人帮互联网科技有限公司 广州淘业互联网络科技 互联网下的科技发展 易互联网科技有限公司 期待互联网科技 小马过河互联网科技 奔汉互联网科技 滨湖区互联网智能科技产品供应 汉立互联网科技有限公司联系电话 北京三清互联网科技 互联网科技实习生岗位职责 华夏互联网科技业 青海科技产业互联网发展 明优互联网科技有限公司 互联网科技如何创业 上海同邻互联网科技有限公司规模 互联网科技接地气 互联网科技收购价值 平安好医生打造互联网科技医疗 银川新华互联网科技学校招聘 百单网互联网科技有限公司 科技平台互联网 迪茉互联网科技 宜安科技 互联网金融 互联网还是高科技吗 科技赋能视角下互联网保险发展 合肥互联网科技公司公章图片 上海科技产业互联网平台 互联网时代科技型公司的机会 宁波允成互联网科技有限公司
0