代码

  1. import com.blade.exception.BeanCopyException;
  2. import java.lang.reflect.Field;
  3. import java.lang.reflect.Method;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.List;
  7. /**
  8. * 深拷贝
  9. */
  10. public class BeanKit {
  11. public static <T> T copy(Object origin, Class<T> destCls) {
  12. T dest = ReflectKit.newInstance(destCls);
  13. copy(origin, dest);
  14. return dest;
  15. }
  16. public static void copy(Object origin, Object dest) {
  17. String fileName, str, getName, setName;
  18. List<Field> fields = new ArrayList<>();
  19. Method getMethod;
  20. Method setMethod;
  21. try {
  22. Class<?> c1 = origin.getClass();
  23. Class<?> c2 = dest.getClass();
  24. Class<?> c1Superclass = c1.getSuperclass();
  25. Class<?> c2Superclass = c2.getSuperclass();
  26. List<Field> fs1 = new ArrayList<>(Arrays.asList(c1.getDeclaredFields()));
  27. //获取源对象父类的所有fields
  28. while (!c1Superclass.equals(Object.class)) {
  29. List<Field> parentFields = Arrays.asList(c1Superclass.getDeclaredFields());
  30. fs1.addAll(parentFields);
  31. c1Superclass = c1Superclass.getSuperclass();
  32. }
  33. List<Field> fs2 = new ArrayList<>(Arrays.asList(c2.getDeclaredFields()));
  34. //获取目标对象所有父类的fields
  35. while (!c2Superclass.equals(Object.class)) {
  36. List<Field> parentFields = Arrays.asList(c2Superclass.getDeclaredFields());
  37. fs2.addAll(parentFields);
  38. c2Superclass = c2Superclass.getSuperclass();
  39. }
  40. // two class attributes exclude different attributes, leaving only the same attributes.
  41. //获取共同的fields
  42. for (Field aFs2 : fs2) {
  43. for (Field aFs1 : fs1) {
  44. if (aFs1.getName().equals(aFs2.getName())) {
  45. fields.add(aFs1);
  46. break;
  47. }
  48. }
  49. }
  50. //如果共同的fields个数>0
  51. if (fields.size() > 0) {
  52. for (Field f : fields) {
  53. fileName = f.getName();
  54. // capitalize the first letter of the property name.
  55. //将field的首字母大写
  56. str = fileName.substring(0, 1).toUpperCase();
  57. // getXXX and setXXX
  58. //get set方法的名字
  59. getName = "get" + str + fileName.substring(1);
  60. setName = "set" + str + fileName.substring(1);
  61. try {
  62. getMethod = c1.getMethod(getName);
  63. setMethod = c2.getMethod(setName, f.getType());
  64. if (null != getMethod && null != setMethod) {
  65. Object o = getMethod.invoke(origin);
  66. if (null != o) {
  67. setMethod.invoke(dest, o);
  68. }
  69. }
  70. } catch (NoSuchMethodException e) {
  71. }
  72. }
  73. }
  74. } catch (Exception e) {
  75. throw new BeanCopyException(e);
  76. }
  77. }
  78. }

测试

BeanKitTest.java

  1. import com.blade.model.MyPerson;
  2. import com.blade.model.Person;
  3. import org.junit.Assert;
  4. import org.junit.Test;
  5. public class BeanKitTest {
  6. @Test
  7. public void testCopy() {
  8. Person source = new Person("jack", "nu", 22);
  9. Person dest = new Person();
  10. BeanKit.copy(source, dest);
  11. Assert.assertEquals(source.toString(), dest.toString());
  12. Person dest2 = BeanKit.copy(source, Person.class);
  13. Assert.assertEquals(source.toString(), dest2.toString());
  14. MyPerson myPerson = BeanKit.copy(source, MyPerson.class);
  15. Assert.assertNotNull(myPerson.getName());
  16. }
  17. }

Person.java

  1. import lombok.Data;
  2. @Data
  3. public class Person {
  4. private String name;
  5. private String text;
  6. private int age;
  7. public Person() {
  8. }
  9. public Person(String name, String text, int age) {
  10. this.name = name;
  11. this.text = text;
  12. this.age = age;
  13. }
  14. }

MyPerson.java

  1. import lombok.Data;
  2. import lombok.EqualsAndHashCode;
  3. import lombok.ToString;
  4. /**
  5. * @author biezhi
  6. * @date 2018/4/9
  7. */
  8. @Data
  9. @ToString(callSuper = true)
  10. @EqualsAndHashCode(callSuper = true)
  11. public class MyPerson extends Person {
  12. private Boolean sex;
  13. }