BeanCopier系列之一:特性测试

本文通过四个测试案例详细介绍了BeanCopier在不同场景下的表现,包括属性名称与类型完全匹配、名称相同但类型不同、目标类缺失setter方法及源目标类setter-getter数量不匹配的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[url=http://czj4451.iteye.com/blog/2044101]BeanCopier系列之二:使用Converter[/url]
[url=http://czj4451.iteye.com/blog/2044150]BeanCopier系列之三:缓存BeanCopier提升性能[/url]


cglib是一款比较底层的操作java字节码的框架。

下面通过拷贝bean对象来测试BeanCopier的特性:


public class OrderEntity {
private int id;
private String name;
// Getters and setters are omitted
}


public class OrderDto {
private int id;
private String name;
// Getters and setters are omitted
}


public class PropWithDiffType {
private Integer id;
private String name;
// Getters and setters are omitted
}


public class LackOfSetter {
private int id;
private String name;

public LackOfSetter() {
}

public LackOfSetter(int id, String name) {
this.id = id;
this.name = name;
}
// Getters and setters are omitted
// public void setName(String name) {
// this.name = name;
// }
}


[size=medium]1. 属性名称、类型都相同:[/size]

@Test
public void normalCopyTest() {
OrderEntity entity = new OrderEntity();
entity.setId(1);
entity.setName("orderName");
final BeanCopier copier = BeanCopier.create(OrderEntity.class, OrderDto.class, false);
OrderDto dto = new OrderDto();
copier.copy(entity, dto, null);
Assert.assertEquals(1, dto.getId());
Assert.assertEquals("orderName", dto.getName());
}

结论:拷贝OK。

[size=medium]2. 属性名称相同、类型不同:[/size]


@Test
public void sameNameDifferentTypeCopyTest() {
OrderEntity entity = new OrderEntity();
entity.setId(1);
entity.setName("orderName");
final BeanCopier copier = BeanCopier.create(OrderEntity.class, PropWithDiffType.class, false);
PropWithDiffType dto = new PropWithDiffType();
copier.copy(entity, dto, null);
Assert.assertEquals(null, dto.getId()); // OrderEntity的id为int类型,而PropWithDiffType的id为Integer类型,不拷贝
Assert.assertEquals("orderName", dto.getName());
}

结论:名称相同而类型不同的属性不会被拷贝。

注意:即使源类型是[color=red]原始类型[/color](int, short和char等),目标类型是其[color=red]包装类型[/color](Integer, Short和Character等),或反之:都[color=red]不会被拷贝[/color]。

[size=medium]3. 源类和目标类有相同的属性(两者的getter都存在),但目标类的setter不存在[/size]

@Test
public void targetLackOfSetterCopyTest() {
OrderEntity entity = new OrderEntity();
entity.setId(1);
entity.setName("orderName");
final BeanCopier copier = BeanCopier.create(OrderEntity.class, LackOfSetter.class, false); // 抛NullPointerException
LackOfSetter dto = new LackOfSetter();
copier.copy(entity, dto, null);
}

结论:创建BeanCopier的时候抛异常。

导致异常的原因是BeanCopier类的第128~133行

for (int i = 0; i < setters.length; i++) { // 遍历目标类的属性描述集
PropertyDescriptor setter = setters[i];
PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName()); // 从源类获取和目标类属性名称相同的属性描述
if (getter != null) {
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod()); // 获取源类属性的getter方法
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod()); // 获取目标类属性的setter方法。LackOfSetter类name属性的setter方法没有,所以报错


[size=medium]4. 源类或目标类的setter比getter少[/size]

@Test
public void sourceLackOfSetterCopyTest() {
LackOfSetter source = new LackOfSetter(1, "throne");
final BeanCopier copier = BeanCopier.create(LackOfSetter.class, OrderDto.class, false);
OrderDto dto = new OrderDto();
copier.copy(source, dto, null);
Assert.assertEquals(1, dto.getId());
Assert.assertEquals("throne", dto.getName());
}

结论:拷贝OK。此时的setter多余,但不会报错。

总结:

1. BeanCopier只拷贝名称和类型都相同的属性。

2. 当目标类的setter数目比getter少时,创建BeanCopier会失败而导致拷贝不成功。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值