利用反射写自动装配类或转换器

工作的时候,时常会遇到需要对一些类重新装配的问题,例如,由于Java传递对象本质上是传引用,直接利用对象类型的参数,可能会修改该参数;但是实际工作中,我们往往不想修参数,但是又希望利用该参数,那怎么办呢?
只好重新拷贝一个对象。
如果该类有几十个字段(实际往往是这样),我们装配对象就太费体力了,而且冗长的装配代码可能也不是我们想要的。那怎么办呢??
(1)对于通用情况的处理
由于类中的字段都是私有的,而访问控制一般借助于相应的get和set方法。那好吧,我们就可以利用反射,遍历所有set方法,然后调用源对象的get方法。ok,通用情况搞定。
(2)如果有例外的字段呢,有些字段并没有get或set方法,有has...或isOpen,之类的方法,直接调用源对象的get方法显然不行。对于这些例外字段,有些需要,有些实际上拷贝的时候可以不要。因此,我们可以实际2个list存放这些字段:
specialFieldNameList 和 needProcessFieldsList ,前者存放所有特殊的字段,后面那个列表存放以上特殊字段中需要进行处理的字段。
ok,明确了需求,可以动工了,代码如下:

public class BaseConverter {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 特殊字段列表,只针对有set方法的属性字段
*/
private List<String> specialFieldNameList = new ArrayList<String>();
/**
* 上述特殊字段列表(specialFieldNameList)中需要进行处理的字段列表
*/
private List<String> needProcessFieldsList = new ArrayList<String>();
/**
* 是否是例外方法
* @param methodName
* @return
*/
public BaseConverter(){}
public BaseConverter(List<String> specialFieldNameList,
List<String> needProcessFieldsList) {
super();
this.specialFieldNameList = specialFieldNameList;
this.needProcessFieldsList = needProcessFieldsList;
}
public boolean isSpecialMethod(String methodName) {
List<String> specialFieldNameList = this.getSpecialFieldNameList();
String targetField = methodName.substring(3, 4).toLowerCase()
+ methodName.substring(4);
if (specialFieldNameList.contains(targetField))
return true;
else
return false;
}
/**
* 处理该特殊方法的返回值
* @param methodName
* @return
*/
public boolean needProcess(String methodName) {
List<String> needProcessFieldsList = this.getNeedProcessFieldsList();
String targetField = methodName.substring(3, 4).toLowerCase()
+ methodName.substring(4);
if (needProcessFieldsList.contains(targetField))
return true;
else
return false;
}


public Object processSpecialMethod(Method targetMethod, Object srcObject,
Object targetObject){
String targetMethodName = targetMethod.getName();
//此处省略 。。。。
targetMethod.invoke(targetObject, value);
} catch (Exception e) {
// e.printStackTrace();
logger.error("[Error:processSpecialMethod....encount an error]",e.getMessage());
}
}
return targetObject;
}
/**
*
* @param targetMethod
* @param srcObject
* @param targetObject
* @return
* @throws Exception
*/
public Object processTargetMethod(Method targetMethod, Object srcObject,
Object targetObject) throws Exception {
String targetMethodName = targetMethod.getName();
// logger.info("[Info:processTargetMethod]:"+ targetMethodName);
if (targetMethodName.substring(0, 3).contains("set")) {
// 先处理一般属性的字段
if (!isSpecialMethod(targetMethodName)) {
// 先处理一般属性的字段
Method srcMethod = srcObject.getClass().getMethod(
("g" + targetMethodName.substring(1)));
Object value = srcMethod.invoke(srcObject);
targetMethod.invoke(targetObject, value);
} else if (needProcess(targetMethodName)) {
targetObject = this.processSpecialMethod(targetMethod,
srcObject, targetObject);
}
}
return targetObject;
}
/**
* DO对象转换
* @param srcObject
* @param targetObject
* @return
* @throws Exception
*/
public Object convertToObject(Object srcObject, Object targetObject) throws Exception {
if(srcObject == null)
return null;
Class<?> targetClass = targetObject.getClass();
Method[] methods = targetClass.getDeclaredMethods();
Method targetMethod;
for (int j = 0; j < methods.length; j++) {
targetMethod = methods[j];
targetObject = this.processTargetMethod(targetMethod, srcObject, targetObject);
targetObject = this.processTargetMethod(targetMethod, srcObject, targetObject);
}
Method[] superMethods = null;
Class<?> superClass;
while ((superClass = targetClass.getSuperclass()) != null) {
superMethods = targetClass.getSuperclass().getDeclaredMethods();
for (int j = 0; j < superMethods.length; j++) {
targetMethod = superMethods[j];
targetObject = this.processTargetMethod(targetMethod,
srcObject, targetObject);
}
targetClass = superClass;
}
return targetObject;
}


public void setSpecialFieldNameList(List<String> specialFieldNameList) {
this.specialFieldNameList = specialFieldNameList;
}

public List<String> getSpecialFieldNameList() {
return specialFieldNameList;
}

public List<String> getNeedProcessFieldsList() {
return needProcessFieldsList;
}

public void setNeedProcessFieldsList(List<String> needProcessFieldsList) {
this.needProcessFieldsList = needProcessFieldsList;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值