`
zhanche2011
  • 浏览: 97891 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多
工作的时候,时常会遇到需要对一些类重新装配的问题,例如,由于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;
	}
}
分享到:
评论

相关推荐

    java注解_反射_字节码_类加载机制.zip

    常见的注解有@Override(确保方法覆盖父类方法)、@Deprecated(标记过时的API)和@Autowired(Spring框架中自动装配依赖)。注解可以自定义,通过元注解如Retention(保留策略)、Target(目标元素)等来定义其行为...

    工业自动化 传感器原理3.rar

    然后通过A/D转换器转变为数字信号,供微处理器或PLC处理。 10. 传感器的选择与应用: 在实际应用中,选择传感器要考虑其测量范围、精度、响应时间、稳定性、环境适应性等因素。同时,还需要考虑系统的集成、兼容性...

    手写一个SpringIoc容器

    可以使用Java的DOM、SAX或StAX API解析XML,或者利用反射API处理注解。 9. **单元测试与调试**:为了确保容器功能的正确性,需要编写单元测试用例。同时,良好的日志记录和调试信息可以方便开发者理解和调试容器。 ...

    行业资料-电子功用-光电接近度开关的说明分析.rar

    光电探测器接收这些反射或透射的光线,并将其转换为电信号。根据接收到的光量变化,开关会输出高电平或低电平,从而判断物体是否接近或者存在。 二、类型 1. 对射式:发射器和接收器分别位于两个独立的单元,光线...

    自动生产线复习试题(卷)含答案解析.doc

    3. PLC的A/D和D/A转换器:CPU224XP上有两路A/D转换器和一路D/A转换器,这表明该PLC能够处理模拟量输入和输出。 4. PPI通信:YL-335B的控制系统采用PPI(串行协议接口)进行通信,这是一种串行总线通信方式,常用于...

    自动化生产线安装与调试-试卷题签与答题纸-卷1.docx

    8. 变频器是应用变频技术制造的一种静止的频率变换器,其功能是利用半导体器件的通断作用将频率(通常为工频50HZ)的交流电(三相或单相)变幻成频率连续可调的交流电源。 9. 二位五通电磁阀,阀芯有五个位置。 10. ...

    最新电气自动化毕业设计论文题目..pdf

    1. **数字电压表设计**:这涉及到信号的采集、量化和显示技术,通常会用到模数转换器(ADC)和微控制器。 2. **红外传输系统**:红外通信技术用于无线数据传输,涉及编码、解码、调制与解调等,适用于短距离通信场景...

    工业自动化 传感器原理1.rar

    7. 光电传感器:利用光的性质变化进行检测,如反射式、透过式和漫射式,广泛应用于颜色识别、物体检测等场景。 8. 化学传感器:如电化学传感器和红外传感器,用于检测环境中的化学物质,如有害气体浓度,保障生产...

    工厂自动化传感器概述(中文版).rar

    3. 光电传感器:基于光的吸收、反射或透射,转换非电量为电信号。 4. 磁感应传感器:如霍尔效应传感器,通过磁场变化影响电子在材料中的移动,产生电压输出。 5. 压电传感器:利用材料在受力时产生的电荷或电压变化...

    行业分类-电子-关于光电位置检测装置的说明分析.rar

    3. 光电编码器:通过光栅盘或光栅尺,利用光的透射和反射,将机械角度转换为电信号,提供高精度的位置信息。 4. 图像传感器:如CCD(电荷耦合器件)和CMOS(互补金属氧化物半导体),捕捉图像并转换成数字信号,可...

    电子功用-拉线式光电位移传感器

    当物体移动时,通过拉线将位移转化为线性变化的光信号,这个光信号经过光学系统的处理后,被光电转换器接收并转换为电信号,最终输出与位移成比例的电压或电流信号,从而实现非接触式的精确测量。 二、结构特点 1. ...

    行业分类-电子-关于平行光入射角度的测量方法和光电角度传感器的介绍分析.rar

    - 使用光学元件如分束器或反射镜引导光线进入测量装置。 - 利用光学探测器,如CCD或CMOS传感器,捕获光线图像。 - 分析探测器接收到的光强分布,计算光线相对于入射面的偏斜角度。 - 应用几何光学原理,如斯涅尔...

    超声波接近开关使用入门.zip

    1. 工业自动化:在生产线上用于检测物料位置,确保机器人的准确抓取或装配。 2. 安全防护:如防盗报警系统,利用超声波探测是否有非法入侵者。 3. 停车辅助:汽车倒车雷达系统,帮助驾驶员判断与障碍物的距离。 4. ...

    法国CROUZET公司光电传感器产品样本.pdf

    它们通常包括一个光源(发射器),如LED或激光,和一个检测器(接收器),用于接收光源发出并被物体反射或遮挡后的光。 光电传感器的工作原理基于光电效应,即当光照射到半导体材料上时,会激发出电子,从而产生...

    行业文档-设计装置-多种传感器测量位移量的物理原理教学综合演示装置.zip

    当物体移动时,会改变光线的传播路径或反射角度,通过光电元件转换成电信号,从而计算出位移量。 2. 电容式传感器:基于电容的改变来测量位移。当两个电极之间的距离变化时,电容量也会随之改变,根据电容的变化...

    C#代码动态编译、动态执行、动态调试.pdf

    动态编译完成后,我们可以使用`Assembly`类的静态方法`Load`或`LoadFrom`加载装配,然后通过反射机制创建并执行类的实例。例如,`Assembly.CreateInstance(typeFullName)`方法能够根据类型全名创建实例。如果存在多...

    行业文档-设计装置-一种介质识别装置.zip

    例如,光电传感器利用光的反射、吸收或透射来识别介质;磁性传感器则通过检测磁场强度变化来识别磁性材料。 该装置的设计过程涉及硬件和软件两部分。硬件部分包括传感器的选择与布局、信号调理电路、微控制器或...

    基于Python的激光跟踪仪设站优化系统的开发.pdf

    激光跟踪仪是一种高精度的测量设备,它通过发射激光束,跟踪目标反射器的位置变化,从而获得目标的精确位置信息。在系统开发中需要了解激光跟踪仪的工作原理和性能指标,以及如何将测量得到的数据与优化系统相结合。...

    行业资料-电子功用-光电目视一体化自准直仪的说明分析.rar

    通过测量光点的位置变化,可以精确地确定反射镜的微小位移,从而推算出被测物体的直线度或角度误差。 2. **光电技术**:光电目视一体化自准直仪的关键在于光电传感器的运用。它能够将接收到的光线信号转换为电信号...

    超声波测距

    超声波测距是一种利用超声波在空气或其他介质中传播并反射的技术,来测量发射与接收之间的时间差,从而计算距离的方法。这种技术广泛应用于各种领域,包括机器人导航、工业自动化、安防系统以及日常生活中的电子设备...

Global site tag (gtag.js) - Google Analytics