BeanUtils.copyProperties 是 Java 开发中常用的工具方法,用于将一个 JavaBean 对象的属性值复制到另一个 JavaBean 对象中,其核心实现依赖于反射机制,主要存在于 Spring Framework 和 Apache Commons BeanUtils 两个库中。
核心区别与选择
- Spring BeanUtils (
org.springframework.beans.BeanUtils) - 方法签名 :
copyProperties(Object source, Object target)。 - 特点 :源对象(source)在前,目标对象(target)在后 。此版本对属性匹配的要求相对宽松,只要目标对象有对应的 setter 方法且源对象有对应的 getter 方法即可尝试复制。
- 方法签名 :
- Apache Commons BeanUtils (
org.apache.commons.beanutils.BeanUtils) - 方法签名 :
copyProperties(Object dest, Object orig)。1 - 特点 :目标对象(dest)在前,源对象(orig)在后 ,参数顺序与 Spring 版本相反。此版本要求源对象中的字段,目标对象必须包含 (可以有额外字段),且字段名称必须严格一致。1
- 方法签名 :
使用要点与特性
- 属性匹配规则
- 名称匹配:默认通过属性名(通过 getter/setter 方法推断)进行匹配。
- 命名转换 :Spring 版本支持驼峰命名到蛇形命名的自动转换(如
userName匹配user_name)。 - 忽略大小写:匹配过程通常会忽略属性名的大小写差异。3
- 浅拷贝与类型处理
- 浅拷贝 :该方法执行的是**浅拷贝(Shallow Copy)**。如果对象属性是引用类型(如自定义对象、集合),复制的是引用地址,而非创建新对象。对于包含嵌套对象的场景,需谨慎考虑是否会影响原始数据。
- 类型转换 :Apache Commons BeanUtils 的
copyProperties会尝试进行自动类型转换 (例如 String 到 Integer),而PropertyUtils.copyProperties则要求类型完全匹配,否则会报错。Spring 版本也会进行类型转换。对于基本类型的包装类(如Integer、Boolean),当源对象属性值为null时,复制到目标对象可能会被转换为默认值(如 0, false)。
高级用法与注意事项
- 忽略特定属性 :两个库的方法都支持传入
ignoreProperties参数,以忽略复制指定的属性。5 - 条件复制 :可以通过继承并重写
BeanUtilsBean类,实现仅在目标属性为null时才复制等自定义逻辑。 - 性能考量 :由于基于反射,频繁或大批量调用时可能影响性能。在性能敏感场景下,可考虑使用
MapStruct、手动setter或对象序列化/反序列化(用于深拷贝)等替代方案。 - 常见应用场景 :该方法广泛应用于 DTO(数据传输对象)与实体(Entity)之间的转换 、表单对象与业务对象的数据绑定 以及服务层与持久层间的数据传递。