代码
import com.blade.exception.BeanCopyException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 深拷贝
*/
public class BeanKit {
public static <T> T copy(Object origin, Class<T> destCls) {
T dest = ReflectKit.newInstance(destCls);
copy(origin, dest);
return dest;
}
public static void copy(Object origin, Object dest) {
String fileName, str, getName, setName;
List<Field> fields = new ArrayList<>();
Method getMethod;
Method setMethod;
try {
Class<?> c1 = origin.getClass();
Class<?> c2 = dest.getClass();
Class<?> c1Superclass = c1.getSuperclass();
Class<?> c2Superclass = c2.getSuperclass();
List<Field> fs1 = new ArrayList<>(Arrays.asList(c1.getDeclaredFields()));
//获取源对象父类的所有fields
while (!c1Superclass.equals(Object.class)) {
List<Field> parentFields = Arrays.asList(c1Superclass.getDeclaredFields());
fs1.addAll(parentFields);
c1Superclass = c1Superclass.getSuperclass();
}
List<Field> fs2 = new ArrayList<>(Arrays.asList(c2.getDeclaredFields()));
//获取目标对象所有父类的fields
while (!c2Superclass.equals(Object.class)) {
List<Field> parentFields = Arrays.asList(c2Superclass.getDeclaredFields());
fs2.addAll(parentFields);
c2Superclass = c2Superclass.getSuperclass();
}
// two class attributes exclude different attributes, leaving only the same attributes.
//获取共同的fields
for (Field aFs2 : fs2) {
for (Field aFs1 : fs1) {
if (aFs1.getName().equals(aFs2.getName())) {
fields.add(aFs1);
break;
}
}
}
//如果共同的fields个数>0
if (fields.size() > 0) {
for (Field f : fields) {
fileName = f.getName();
// capitalize the first letter of the property name.
//将field的首字母大写
str = fileName.substring(0, 1).toUpperCase();
// getXXX and setXXX
//get set方法的名字
getName = "get" + str + fileName.substring(1);
setName = "set" + str + fileName.substring(1);
try {
getMethod = c1.getMethod(getName);
setMethod = c2.getMethod(setName, f.getType());
if (null != getMethod && null != setMethod) {
Object o = getMethod.invoke(origin);
if (null != o) {
setMethod.invoke(dest, o);
}
}
} catch (NoSuchMethodException e) {
}
}
}
} catch (Exception e) {
throw new BeanCopyException(e);
}
}
}
测试
BeanKitTest.java
import com.blade.model.MyPerson;
import com.blade.model.Person;
import org.junit.Assert;
import org.junit.Test;
public class BeanKitTest {
@Test
public void testCopy() {
Person source = new Person("jack", "nu", 22);
Person dest = new Person();
BeanKit.copy(source, dest);
Assert.assertEquals(source.toString(), dest.toString());
Person dest2 = BeanKit.copy(source, Person.class);
Assert.assertEquals(source.toString(), dest2.toString());
MyPerson myPerson = BeanKit.copy(source, MyPerson.class);
Assert.assertNotNull(myPerson.getName());
}
}
Person.java
import lombok.Data;
@Data
public class Person {
private String name;
private String text;
private int age;
public Person() {
}
public Person(String name, String text, int age) {
this.name = name;
this.text = text;
this.age = age;
}
}
MyPerson.java
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* @author biezhi
* @date 2018/4/9
*/
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class MyPerson extends Person {
private Boolean sex;
}