日常java開發過程中會涉及到Bean類型轉換過程,即從一個Bean通過屬性拷貝的方式生成另一個Bean
通常代碼如下:
TargetBean target=new TargetBean();
BeanUtils.copyProperties(param,target);
注:這裏我用的是org.springframework.beans.BeanUtils
但是這種方式,是屬性名完全相同的的情況下才能複製屬性,
比如這種情況下 A 的屬性 dwMap 到 B的屬性 dwmap就無法複製。下面給出忽略大小寫轉換拷貝bean的寫法
採用下面這種方法,dwMap 成員和dwmap成員會被認爲是相同變量而發生屬性複製
/**
* 忽略大小寫轉換bean類型
*
* @param obj 轉換的源對象
* @param clz 目標對象
* @return 轉換後的對象
*/
public static <T> T transferObjectIgnoreCase(Object obj, Class clz) {
T result = null;
try {
if (obj != null && !obj.equals("")) {
result = (T) clz.newInstance();
//獲取目標類的屬性集合
Map<String, Field> destPropertyMap = new HashMap<>();
for (Field curField : clz.getDeclaredFields()) {
destPropertyMap.put(curField.getName().toLowerCase(), curField);
}
//拷貝屬性
for (Field curField : obj.getClass().getDeclaredFields()) {
Field targetField = destPropertyMap.get(curField.getName().toLowerCase());
if (targetField != null) {
targetField.setAccessible(true);
curField.setAccessible(true);
targetField.set(result, curField.get(obj));
}
}
}
} catch (Exception e1) {
return null;
}
return result;
}
使用示例如下
Result result = PropertyUtils.transferObject(param,Result.class);
代碼解析
我來解釋下代碼(<T>是函數模板,這我就不多說了,不知道要好好看看java基礎了,)
首先手機目標類的成員,並存到map
//獲取目標類的屬性集合
Map<String, Field> destPropertyMap = new HashMap<>();
for (Field curField : clz.getDeclaredFields())
destPropertyMap.put(curField.getName().toLowerCase(), curField);
這種是用map保存目標類的所有屬性,方便與源參數的屬性進行比對,判斷是不是擁有可以拷貝的屬性。如果不用map的話,你可以能就要用兩層for循環進行循環比對了,這樣效率很低,比如這個bean有20個屬性,另一個bean有20個屬性的,最差情況下要進行400次比對。用map的比對最差的情況下就是20次
下面將源參數的屬性名轉換成小寫(toLowerCase)和目標類的屬性進行比對
//拷貝屬性 for (Field curField : obj.getClass().getDeclaredFields()) { Field targetField = destPropertyMap.get(curField.getName().toLowerCase()); if (targetField != null) { targetField.setAccessible(true); curField.setAccessible(true); targetField.set(result, curField.get(obj)); } }
如果目標類中存在相同名稱屬性時,通過Field.set和Field的get方式進行屬性拷貝
這樣就完成了屬性拷貝的過程。
注:我這沒做類型轉換的,複製的屬性必須類型相同的,你可以自己擴展哦