在系統對接中,常需將前置系統的對象轉換為內部領域對象,再經處理後轉回。手寫 set/get 代碼冗長且難維護,本文提供基於反射的通用拷貝工具,支持基本類型、包裝類、String、Date 及巢狀對象遞歸拷貝。
getDeclaredFields()。setAccessible(true)。isXxx,其餘 getXxx)。public class BeanCopier {
public static void copy(Object src, Object dest) throws Exception {
doField(src, dest);
}
private static void doField(Object src, Object dest) throws Exception {
Field[] srcFields = src.getClass().getDeclaredFields();
Field[] destFields = dest.getClass().getDeclaredFields();
for (Field sf : srcFields) {
boolean accessible = sf.isAccessible();
sf.setAccessible(true);
String name = sf.getName();
String getter = (sf.getType() == boolean.class || sf.getType() == Boolean.class) ? "is" + capitalize(name) : "get" + capitalize(name);
Method getMethod = src.getClass().getDeclaredMethod(getter);
Object value = getMethod.invoke(src);
for (Field df : destFields) {
if (df.getName().equals(name)) {
df.setAccessible(true);
if (isPrimitiveOrWrapper(df.getType())) {
// 基本類型、包裝類、String、Date 直接賦值
if (df.getType() == boolean.class || df.getType() == Boolean.class) {
df.set(dest, "1".equals(value) ? true : false); // 兼容字符串 "1"/"0"
} else {
df.set(dest, value);
}
} else {
// 巢狀對象:創建實例並遞歸拷貝
Object nestedDest = df.getType().getDeclaredConstructor().newInstance();
doField(value, nestedDest);
df.set(dest, nestedDest);
}
System.out.println(df.getName() + ":" + df.get(dest));
break;
}
}
sf.setAccessible(accessible);
}
}
private static boolean isPrimitiveOrWrapper(Class<?> clazz) {
return clazz.isPrimitive() || clazz == String.class || clazz == Date.class ||
clazz == Byte.class || clazz == Short.class || clazz == Integer.class ||
clazz == Long.class || clazz == Float.class || clazz == Double.class ||
clazz == Character.class || clazz == Boolean.class;
}
private static String capitalize(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}
MtUserInfoRule src = new MtUserInfoRule(); // 設置 src 各字段及巢狀對象 Person -> Student UserInfoRule dest = new UserInfoRule(); BeanCopier.copy(src, dest); // 一行代碼完成深拷貝
String[]、List<T>)未完全支持,需增加集合實例化與元素遞歸邏輯。@Mapping("targetField") 指定映射。