今天将项目的分支代码合并到主干时,发现原本运行正常的代码在测试服务器上竟然出错,后来分析发现是代码合并时,有人把BeanUtils替换成了PropertyUtils,导致copyProperties方法在执行时不能自动转换属性的数据类型,下面详细分析:
首先两者来源于同一个包:
1 import org.apache.commons.beanutils.BeanUtils; 2 import org.apache.commons.beanutils.PropertyUtils;
BeanUtils提供对java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。因为一个JavaBean通常包含了大量的属性,很多情况下,对JavaBean的处理导致大量get/set代码堆积,增加了代码长度和阅读代码的难度,直接使用对象实体复制可增加代码的辨识度并且方便维护。
BeanUtils和PropertyUtils俩者的共同点:
1、通过反射将一个对象的值赋值个另外一个对象(前提是对象中属性的名字相同);
2、PropertyUtils和BeanUtils的copyProperties(obj1,obj2); 经常闹混不知道是谁给谁赋值,“先到后付前"这个词来帮助自己记忆这个功能。即将obj2的值赋值给obj1;
3、如果2中实例obj2为空对象,即值new了他的实例并没有赋值的话obj1对应的属性值也会被设置为空置;
俩者的不同点:BeanUtils与PropertyUtils对比(这里对比copyProperties方法)
PropertyUtils的copyProperties()方法与BeanUtils.copyProperties()几乎相同,主要的区别在于后者提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,PropertyUtils不支持这个功能,所以说BeanUtils速度会更快一些,使用更普遍一点,犯错的风险更低一点。
举个例子:创建两个对象,然后 给一个对象赋值 最后把已经赋值的对象 copy到另一个空对象里面:
1 public class Person { 2 private String name; 3 private String sex; 4 private String age; 5 private Date birthday; 6 7 public String getName() { 8 return name; 9 } 10 11 public void setName(String name) { 12 this.name = name; 13 } 14 15 public String getSex() { 16 return sex; 17 } 18 19 public void setSex(String sex) { 20 this.sex = sex; 21 } 22 23 public String getAge() { 24 return age; 25 } 26 27 public void setAge(String age) { 28 this.age = age; 29 } 30 31 public Date getBirthday() { 32 return birthday; 33 } 34 35 public void setBirthday(Date birthday) { 36 this.birthday = birthday; 37 } 38 }
1 public class Student { 2 private String name; 3 private String sex; 4 private Integer age; 5 private Date birthday; 6 7 public String getName() { 8 return name; 9 } 10 11 public void setName(String name) { 12 this.name = name; 13 } 14 15 public String getSex() { 16 return sex; 17 } 18 19 public void setSex(String sex) { 20 this.sex = sex; 21 } 22 23 public Integer getAge() { 24 return age; 25 } 26 27 public void setAge(Integer age) { 28 this.age = age; 29 } 30 31 public Date getBirthday() { 32 return birthday; 33 } 34 35 public void setBirthday(Date birthday) { 36 this.birthday = birthday; 37 } 38 39 @Override 40 public String toString() { 41 return "Student{" + 42 "name='" + name + '\'' + 43 ", sex='" + sex + '\'' + 44 ", age=" + age + 45 ", birthday=" + birthday + 46 '}'; 47 } 48 }
public class Test { public static void main(String[] args) throws Exception{ Student student= new Student(); Person person = new Person(); person.setAge(23); person.setName("zhangsan"); person.setSex("nan"); person.setBirthday(new Date()); //PropertyUtils.copyProperties(student, person); BeanUtils.copyProperties(student, person); System.out.println(student.toString()); } }
打印结果:
Student{name='zhangsan', sex='nan', age=23, birthday=Thu Nov 24 10:32:10 CST 20
在执行 BeanUtils.copyProperties(student, person)时 如果把student对象的age 类型换成String是可以打印出正常的结果。但是PropertyUtils.copyProperties(student, person)就会抛出异常。