利用反射进行对象属性值的拷贝,以及对其进行的二次修改另作他用

8月24日老师讲了一个利用反射手动实现对象属性的拷贝的例子:代码如下:

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test1 {
	
	/**
	 * 将对象属性的值拷贝到目标对象中
	 * @param clazz     目标对象的全路径名
	 * @param srcObj    源对象
	 * @return          目标对象
	 * @throws Exception 
	 */
	public static Object copyProperties(String clazz,Object srcObj) throws Exception{
		Object targetObj=null;
		//1、获得源对象和目标的Class
		Class srcClass=srcObj.getClass();//获得Class的第一种
		Class targetClass=Class.forName(clazz);//获得Class的第三种
//		Class clazz3=Object.class;//获得Classr的第三种
		
		targetObj=targetClass.newInstance();//创建目标对象的实例(必须提供无参构造),相当于new Object()
		
		//2、获得目标对象的所有属性
		Field[] targetFields=targetClass.getDeclaredFields();//本类
//		Field[] targetFields=targetClass.getFields();//获得本类或继承过来的所有public
		
		//3、遍历
		if(targetFields!=null && targetFields.length>0){
			for(Field targetField:targetFields){
				//3.1、获得目标对象的属性名
				String targetFieldName=targetField.getName();//获得字段的属性名
				Class targetFieldType=targetField.getType();//获得字段的类型
				
				//3.2、获得源对象的该属性名对应的getXxx()方法对象
				String srcMethodName="get"+targetFieldName.substring(0, 1).toUpperCase()
						+targetFieldName.substring(1);
				Method srcMethod=srcClass.getDeclaredMethod(srcMethodName, null);
				if(srcMethod!=null){//该属性对应的源方法名存在
					Object srcMethodvalue=srcMethod.invoke(srcObj, null);//执行源方法
					//3.3、判断执行源方法之后是否有值,如果有值再去执行目标方法的setXxx()方法
					if(srcMethodvalue!=null){
						String tagetMethodName="set"+targetFieldName.substring(0, 1).toUpperCase()
								+targetFieldName.substring(1);
						Method targetMethod=targetClass.getDeclaredMethod(tagetMethodName, targetFieldType);
						if(targetMethod!=null){
							targetMethod.invoke(targetObj, srcMethodvalue);
						}
					}
				}
			}
		}
		
		return targetObj;
	}
	
	public static void main(String[] args) throws Exception {
		//将StuInfo的属性值复制给Student对象
		StuInfo stu1=new StuInfo(1,"test1","男",18,"广工");
		Student stu2=(Student) copyProperties("com.demo9.Student", stu1);
		System.out.println("stu1:"+stu1);
		System.out.println("stu2:"+stu2);
	}
}

今天修改了这个类,利用反射让他把更新的员工信息保存到原来的对应属性中(覆盖数据,没修改的属性信息也重新改一遍,值和原来一样),(在BaseDao中做的是全表修改,且sql语句中的占位符等不能改变)所以,这个方法可以免去手动set每个员工的属性信息。

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BeanUtils {
	/**
	 * 将对象属性的值拷贝到目标对象中
	 *     1)遍历目标对象的所有字段
	 *     2)根据目标对象的字段名去获取源对象的方法==>获得源对象的属性值,判断是否为空,不为空才会设置目标对象中
	 * @param clazz     目标对象的全路径名
	 * @param srcObj    源对象
	 * @return          目标对象
	 * @throws Exception 
	 */
	public static void copyProperties(Object targetObj,Object srcObj) throws Exception{
		//1、获得源对象和目标的Class
		Class srcClass=srcObj.getClass();
		Class targetClass=targetObj.getClass();
		
		//2、获得目标对象的所有属性
		Field[] targetFields=targetClass.getDeclaredFields();//本类
		
		//3、遍历
		if(targetFields!=null && targetFields.length>0){
			for(Field targetField:targetFields){
				//3.1、获得目标对象的属性名
				String targetFieldName=targetField.getName();//获得字段的属性名
				Class targetFieldType=targetField.getType();//获得字段的类型
				
				//3.2、获得源对象的该属性名对应的getXxx()方法对象
				String srcMethodName="get"+targetFieldName.substring(0, 1).toUpperCase()
						+targetFieldName.substring(1);
				Method srcMethod=srcClass.getDeclaredMethod(srcMethodName, null);
				if(srcMethod!=null){//该属性对应的源方法名存在
					Object srcMethodvalue=srcMethod.invoke(srcObj, null);//执行源方法
					//3.3、判断执行源方法之后是否有值,如果有值再去执行目标方法的setXxx()方法
					if(srcMethodvalue!=null){
						String tagetMethodName="set"+targetFieldName.substring(0, 1).toUpperCase()
								+targetFieldName.substring(1);
						Method targetMethod=targetClass.getDeclaredMethod(tagetMethodName, targetFieldType);
						if(targetMethod!=null){
							targetMethod.invoke(targetObj, srcMethodvalue);
						}
					}
				}
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/sinat_41897556/article/details/82220688