比较简陋, 肯定有逻辑漏洞, 请见谅哈!
package devi.mint.reflect;
import devi.mint.entity.UserEntity;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 运用反射复制对象
*
* 前提: 在已有一个对象的情况下, 复制一个一模一样的对象, 引用不一样, 其他东西都一样的。
* 模拟 clone 方法
*/
public class CopyObject {
public static void main(String[] args) {
UserEntity user1 = new UserEntity(1, "张三", 18);
UserEntity user2 = copyObject(user1);
UserEntity user3 = user1.getClone();
System.out.println("原始对象: user1: " + user1);
System.out.println("反射编写的 复制方法: user2: " + user2);
System.out.println("java 自带 clone 方法:user3: " + user3);
}
/**
* 根据对象复制对象
* @param origin 被复制的对象
* @return 新对象
*/
public static UserEntity copyObject(UserEntity origin) {
Class<? extends UserEntity> originClass = origin.getClass();
//根据模板生成空对象
UserEntity destination = null;
try {
destination = originClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
//给新对象赋值
Method[] originMethods = originClass.getMethods();
assert destination != null;
Method[] destinationMethods = destination.getClass().getMethods();
if (originMethods.length == 0 && destinationMethods.length == 0) {
throw new RuntimeException("该对象没有get 和 set 方法");
}
//给新对象赋值
for (Method originMethod : originMethods) {
//取到旧对象的 set 方法
if (! "set".equals(originMethod.getName().substring(0,3))) {
continue;
}
//取到对应属性的set方法
String originGetMethodName = originMethod.getName().replaceFirst("set", "get");
Method originGetMethod = null;
try {
originGetMethod = originClass.getMethod(originGetMethodName);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
//取到新对象的 同名 set 方法, 进行赋值
for (Method destinationMethod : destinationMethods) {
if (originMethod.getName().equals(destinationMethod.getName())) {
try {
assert originGetMethod != null;
destinationMethod.invoke(destination, originGetMethod.invoke(origin));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return destination;
}
}