package com.java1029.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class CopyObject {
/**
* 对象的拷贝(对象必须遵循JavaBean规范)
*
* 1.获取所有的Field对象
* 2.遍历所有的Field对象
* 3.获取对应Field对象的setXX()/getXX()方法的Name
* 4.通过3步获取的方法的Name,获取被复制对象t对应属性Field的getXX()/setXX()方法的Method对象
* (注:4步中获取setXX()对应的Method对象需要参数类型,该类型可以通过geXX()方法对应的Method获取)
* 5.获取getXX方法返回值para:执行getXX()方法对应的Method对象的invoke(t)方法。参数应该为t和null,null课省略
* 6.为新建的对象o执行setXX()方法:用setXX()对象对应的Method对象,执行invoke(o,para)方法。参数应该为新建对象o和5中获取的返回值para
* @param t
* @return
* @throws Exception
*/
public static <T> T copy(T t) throws Exception {
// 获得对象参数类型T的运行期间对象
Class<?> clz = t.getClass();
Field[] fields = clz.getDeclaredFields();
Object o = clz.newInstance();
for (Field f : fields) {
String fieldName = f.getName();
//首字母大写
String firstLetter = fieldName.substring(0, 1).toUpperCase();
// get方法的方法名
String getMethodName = "get" + firstLetter + fieldName.substring(1);
// set方法的方法名
String setMethodName = "set" + firstLetter + fieldName.substring(1);
Method getMethod = clz.getMethod(getMethodName);
// 该属性对应的set方法的返回值类型的Class对象
Class<?> getMethodReturnType = getMethod.getReturnType();
//Method setMethod = clz.getMethod(setMethodName, new Class<?>[]{f.getType()});
//以上代码可以替换下行代码(上行代码是利用该对应Field对象的类型设置setXxx()方法的参数类型)
Method setMethod = clz.getMethod(setMethodName, getMethodReturnType);
// 通过get方法获取t对象的对应该属性的值,来作为o对象set方法的参数
Object para = getMethod.invoke(t);
//为o对象调用该属性对应的set方法
setMethod.invoke(o, para);
}
return (T) o;// 应该返回新的对象
}
public static void main(String[] args) throws Exception {
Student s = new Student();
s.setAge(5);
s.setName("c10");
Student o = CopyObject.copy(s);
System.out.println("o.getName()->"+o.getName());
System.out.println("o.getAge()->"+o.getAge());
}
}
/**
* 学生类
* @author ml1990s
*
*//*
class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
*/
以下为使用内省类java.beans.Introspector 实现对象复制
package com.java1029.reflect.emphasis;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
public class CopyObjectUseBeans {
/**
* 对象的拷贝(对象必须遵循JavaBean规范)
*
* @param t
* @return
* @throws Exception
*/
public static <T> T copy(T t) throws Exception {
// 获得对象参数类型T的运行期间对象
Class<?> clz = t.getClass();
T o = (T) clz.newInstance();
//通过Introspector内省类 获取BeanInfo 描述T的Bean类信息类
BeanInfo beanInfo = Introspector.getBeanInfo(clz);
//
PropertyDescriptor[] descs = beanInfo.getPropertyDescriptors();
for(int i=0,length = descs.length;i<length;i++){
PropertyDescriptor desc = descs[i];
if(!desc.getName().equals("class")){
Method getMethod = desc.getReadMethod();
Method setMethod = desc.getWriteMethod();
System.out.println(setMethod);
Object property = getMethod.invoke(t);
setMethod.invoke(o, property);
}
}
return o;// 应该返回新的对象
}
public static void main(String[] args) throws Exception {
Student s = new Student();
s.setAge(5);
s.setName("c10");
Student o = CopyObjectUseBeans.copy(s);
System.out.println("o.getName()->" + o.getName());
System.out.println("o.getAge()->" + o.getAge());
}
}
/**
* 学生类
*
* @author ml1990s
*
*/
/*
* class Student { private String name; private int age; public String getName()
* { return name; } public void setName(String name) { this.name = name; }
* public int getAge() { return age; } public void setAge(int age) { this.age =
* age; } }
*/