BeanUtils.copyProperties()实现两个实体类中某一些字段的复制

这段代码展示了如何使用BeanUtils工具类从一个User对象复制属性到另一个User对象,同时排除特定字段。user1的identitycard和id被复制到user,而user2的username被复制到user。
   User user = new User();
            user.setUsername("root");
            User user1 = new User();
            user1.setIdentitycard("5555"
`BeanUtils.copyProperties()` **不会报错**,即使两个实体类字段名有的相同、有的不同。 它只会**自动复制字段名相同且类型兼容的属性**,对于字段名不同的属性会**直接忽略**,不会抛异常。 --- ### ✅ 示例说明 假设我们有两个类: ```java public class User { private String name; private int age; private String email; // getter 和 setter 省略 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } public class UserDTO { private String name; private int age; private String phoneNumber; // 字段名不同(email -> phoneNumber) // getter 和 setter 省略 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } } ``` 使用 `BeanUtils.copyProperties()`: ```java import org.springframework.beans.BeanUtils; User user = new User(); user.setName("张三"); user.setAge(25); user.setEmail("zhangsan@example.com"); UserDTO userDTO = new UserDTO(); BeanUtils.copyProperties(user, userDTO); System.out.println("name: " + userDTO.getName()); // 输出: 张三 System.out.println("age: " + userDTO.getAge()); // 输出: 25 System.out.println("phoneNumber: " + userDTO.getPhoneNumber()); // 输出: null(未复制) ``` --- ### 🔍 原理解释 - `BeanUtils.copyProperties(source, target)` 内部通过 Java 的 **内省(Introspection)** 机制获取两个类的 `PropertyDescriptor`。 - 它会遍历 `target` 类的所有 **可写属性(writeable properties)**。 - 如果 `source` 类中存在同名属性,并且类型兼容(或可通过简单转换),就调用 getter 读取并设置到 target。 - **字段名不同的属性会被跳过,不触发错误。** > ⚠️ 注意:如果类型不兼容且无法自动转换(比如 String → Date 没有注册编辑器),可能会抛 `IllegalArgumentException`,但**字段不存在绝不会报错**。 --- ### 🛠 如何处理字段名不同的情况? #### 方法一:手动赋值补充 ```java BeanUtils.copyProperties(user, userDTO); userDTO.setPhoneNumber(user.getEmail()); // 手动映射 ``` #### 方法二:使用 MapStruct(推荐) 支持自定义字段映射: ```java @Mapper public interface UserMapper { UserMapper INSTANCE = Mappers.getMapper(UserMapper.class); @Mapping(source = "email", target = "phoneNumber") UserDTO toDto(User user); } ``` 这样就能把 `email` 映射到 `phoneNumber`。 --- ### ❓常见疑问解答 | 问题 | 回答 | |------|------| | 字段名不同会报错吗? | ❌ 不会,只是不复制 | | 类型不同会怎样? | 若可自动转换(如 int ↔ Integer)则成功;否则可能抛异常 | | 私有字段复制吗? | ✅ 可以,只要提供了 public 的 getter/setter | | 嵌套对象如何处理? | 浅拷贝:只复制引用地址;需深拷贝请另做处理 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一写代码就开心

你的打赏将是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值