日常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方式进行属性拷贝
这样就完成了属性拷贝的过程。
注:我这没做类型转换的,复制的属性必须类型相同的,你可以自己扩展哦