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);
}
}
}
}
}
}
}