利用反射实现对象拷贝功能。
public class MainTest {
public static void main(String[] args) throws Exception{
Auth auth = new Auth(1L, "yang", 30);
Blog blog = new Blog(100L, "hello", auth);
Object copyBlog = copy(blog);
System.out.println("----after copy---- " + copyBlog);
}
public static Object copy(Object sourceObject) throws Exception{
// 获取源对象类型
Class<?> clazz = sourceObject.getClass();
// 方式1.newInstance()
Object targetObject = clazz.newInstance();
// //方式2. 获取源对象构造函数
// Constructor<?> construtctor = clazz.getConstructor();
// // 实例化出目标对象
// Object targetObject = construtctor.newInstance();
// 获得源对象所有属性
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
String firstName = fieldName.substring(0,1).toUpperCase();
String getMethodName = "get" + firstName + fieldName.substring(1);
//获取get方法对象
Method getMethod = clazz.getDeclaredMethod(getMethodName, new Class[]{});
//获取源对象的成员变量的值
Object value = getMethod.invoke(sourceObject, new Object[]{});
String setMethodName = "set" + firstName + fieldName.substring(1);
//获取set方法对象
Method setMethod = clazz.getDeclaredMethod(setMethodName, new Class[]{field.getType()});
//调用set方法将这个值复制到新的对象中去
setMethod.invoke(targetObject, new Object[]{value});
}
return targetObject;
}
}
@Data
class Blog {
private Long id;
private String title;
private Auth auth;
public Blog() {
}
public Blog(Long id, String title, Auth auth) {
this.id = id;
this.title = title;
this.auth = auth;
}
@Override
public String toString() {
return "Blog{" +
"id=" + id +
", title='" + title + '\'' +
", auth=" + auth +
'}';
}
}
@Data
class Auth {
private Long id;
private String name;
private Integer age;
public Auth() {
}
public Auth(Long id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
}
输出结果:
----after copy---- Blog{id=100, title='hello', auth=Auth(id=1, name=yang, age=30)}
注意事项:
必须有空的构造方法,因为clazz.newInstance();会调用空的构造函数。