记录一次对象属性拷贝中反射的应用

本文探讨了如何使用反射机制实现对象属性拷贝,比较了BeanUtil.copyProperties方法和自定义的copyMatchedFields方法,强调了在使用时需确保源对象和目标对象字段名及类型的一致性。
摘要由CSDN通过智能技术生成
记录一次对象属性拷贝中反射的应用
1.常用反射机制的方法

常用的反射机制,比如BeanUtil.copyProperties(),是一种常见的用于对象属性拷贝的工具方法。它通常用于将一个对象的属性值复制到另一个对象中。

简单的使用示例:

1. 创建源对象和目标对象:
   ```
   SourceObject source = new SourceObject();
   TargetObject target = new TargetObject();
   ```

2. 使用`BeanUtil.copyProperties()`进行属性拷贝:
   ```
   BeanUtils.copyProperties(source, target);
   ```

   该方法会自动将源对象的属性值拷贝到目标对象中,前提是源对象和目标对象拥有相同的属性名和类型。如果属性名不一致,可以考虑使用`@PropertyName`注解进行映射。

   ```
   BeanUtils.copyProperties(source, target, "propertyName1", "propertyName2");
   ```

   在这种情况下,只有在显式指定的属性名匹配时,属性值才会被拷贝。
2.尝试仿写

我们试着简单写一个类似的方法,即根据属性名和类型将源对象的属性值复制到目标对象中。

copyMatchedFields

//反射将一个实体类的字段保存到另一个
    public static <T1, T2> void copyMatchedFields(T1 source, T2 target) throws Exception {
        Field[] sourceFields = source.getClass().getDeclaredFields();
        Field[] targetFields = target.getClass().getDeclaredFields();
        for (Field sourceField : sourceFields) {
            for (Field targetField : targetFields) {
                if (sourceField.getName().equals(targetField.getName())
                        && sourceField.getType().equals(targetField.getType())) {
                    sourceField.setAccessible(true);
                    targetField.setAccessible(true);
                    Object value = sourceField.get(source);
                    targetField.set(target, value);
                }
            }
        }
    }

//使用
copyMatchedFields(source, target);

大体解释一下

  1. 使用泛型 <T1, T2>,表示该方法可以处理不同类型的源对象和目标对象。

  2. 通过 source.getClass().getDeclaredFields() 获取源对象的字段数组,通过 target.getClass().getDeclaredFields() 获取目标对象的字段数组。

  3. 使用两个循环遍历源对象和目标对象的字段。

  4. 判断源对象和目标对象的字段名以及字段类型是否匹配。

    • sourceField.getName().equals(targetField.getName()) 判断字段名是否相同。

    • sourceField.getType().equals(targetField.getType()) 判断字段类型是否相同。

  5. 设置可访问性为 true,以便在私有字段上进行操作:sourceField.setAccessible(true)targetField.setAccessible(true)

  6. 使用 sourceField.get(source) 获取源对象字段的值。

  7. 使用 targetField.set(target, value) 将源对象字段的值设置到目标对象字段上。

需要注意的是,该方法只会复制属性名和类型匹配的字段。如果源对象和目标对象具有相同名称但类型不匹配的字段,这个方法将不会复制它们的值。

3.注意事项

这里要注意一下,如果源对象和目标对象存在不同的字段,使用我们的方法或BeanUtils.copyProperties()方法时会尽可能拷贝相同字段名和类型的属性值。对于不同字段名或类型的属性,将不会进行拷贝。

如果源对象和目标对象中存在不同的字段,在调用BeanUtils.copyProperties()方法时会忽略这些不同的字段,不会导致执行失败。仅会拷贝源对象和目标对象中具有相同字段名和类型的属性值。

这是因为BeanUtils.copyProperties()方法将根据字段名和类型进行匹配和拷贝,如果字段名或类型不匹配,则会被忽略。

这里我们做一个验证

public class SourceObject {
    private String field1;
    private int field2;
    //...

    // getter and setter
}

public class TargetObject {
    private String field1;
    private boolean field3;
    //...

    // getter and setter
}

SourceObject source = new SourceObject();
source.setField1("value1");
source.setField2(10);

TargetObject target = new TargetObject();
BeanUtils.copyProperties(source, target);

System.out.println(target.getField1());  // 输出:value1
System.out.println(target.isField3());   // 输出:false(boolean的默认值)

在上述验证示例中,SourceObjectTargetObject具有不同的字段 field2field3。通过BeanUtils.copyProperties()方法,只有字段名为 field1 的属性值被成功拷贝到目标对象 TargetObject 中。其他字段名不匹配的属性将会被忽略。

因此,在使用BeanUtils.copyProperties()方法时,请确保源对象和目标对象中需要拷贝的字段具有相同的字段名和类型,以确保属性的拷贝可以顺利进行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值