package com.lin.test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ObjectClone {
public static void main(String[] args) throws Exception,
IllegalAccessException, Exception {
Person jack = new Person("jack", 24, "hangzhou");
Person brown = new Person("brown", 54, "hangzhou");
jack.setFather(brown);
brown.setArray(new String[]{"lin","feng"});
String[] arr = { "lin", "fu" };
jack.setArray(arr);
Person lily = new Person();
copyProperties(lily,jack);
jack.getFather().setAddress("shanghai");
jack.setAddress("test");
System.out.println("jack" + jack.toString());
System.out.println("lily" + lily.toString());
System.out.println("jack.father:" + jack.getFather());
System.out.println("lily.father:" + lily.getFather());
}
public static void copyProperties(Object destObj,Object srcObj) throws Exception {
// 取得拷貝對(duì)象的所有域
Field[] fieldsBase = srcObj.getClass().getDeclaredFields();
Field.setAccessible(fieldsBase, true);
// 取得目標(biāo)對(duì)象的所有域
Field[] fieldsObj = destObj.getClass().getDeclaredFields();
Field.setAccessible(fieldsObj, true);
for (int i = 0; i < fieldsObj.length; i++) {
// 取得域名稱
Field fieldObj = fieldsObj[i];
for (int j = 0; j < fieldsBase.length; j++) {
Field fieldBase = fieldsBase[j];
// 比較兩域名稱是否一致
if (fieldObj.getName().equals(fieldBase.getName())) {
// 取得域名稱并將第一個(gè)字母大小
String fieldName = fieldObj.getName();
String firstChar = fieldName.substring(0, 1).toUpperCase();
fieldName = firstChar + fieldName.substring(1);
// 取得目標(biāo)對(duì)象中的set方法
Method methodObj = destObj.getClass().getMethod(
"set" + fieldName,
new Class[] { fieldObj.getType() });
// 取得參照對(duì)象中的get方法
Method methodGet = srcObj.getClass().getMethod(
"get" + fieldName, null);
// 執(zhí)行參照對(duì)象的get方法并取得返回值
Object resultObj = methodGet.invoke(srcObj, null);
// 執(zhí)行目標(biāo)對(duì)象的set方法并進(jìn)行設(shè)值
methodObj.invoke(destObj, new Object[] { resultObj });
break;
}
}
}
}
// 深層克隆,主要利用一個(gè)遞歸調(diào)用
public static Object cloneExt(Object obj) throws Exception {
// getDeclaredFields得到object內(nèi)定義的所有field
Field[] fields = obj.getClass().getDeclaredFields();
// 利用newInstance方法,生成一個(gè)空的Object
Object newObj = obj.getClass().newInstance();
for (int i = 0, j = fields.length; i < j; i++) {
String propertyName = fields[i].getName();
// field的值
Object propertyValue = getProperty(obj, propertyName);
// field的類型
String propertyType = fields[i].getType().getName();
if (propertyValue != null) {
// 如果field不是8種基本類型,或者String,則直接賦值
if (propertyType.endsWith("String")
|| "char".equals(propertyType)
|| "int".equals(propertyType)
|| "boolean".equals(propertyType)
|| "byte".equals(propertyType)
|| "short".equals(propertyType)
|| "double".equals(propertyType)
|| "long".equals(propertyType)
|| "float".equals(propertyType)
|| "void".equals(propertyType)) {
setProperty(newObj, propertyName, propertyValue);
} else {
// 如果field類型是其他Object,則遞歸克隆一下
Object newPropObj = cloneExt(propertyValue);
setProperty(newObj, propertyName, newPropObj);
}
}
}
return newObj;
}
// 淺層克隆
public static Object clone(Object obj) throws Exception {
Field[] fields = obj.getClass().getDeclaredFields();
Object newObj = obj.getClass().newInstance();
for (int i = 0, j = fields.length; i < j; i++) {
String propertyName = fields[i].getName();
Object propertyValue = getProperty(obj, propertyName);
setProperty(newObj, propertyName, propertyValue);
}
return newObj;
}
// 反射調(diào)用setter方法,進(jìn)行賦值
private static Object setProperty(Object bean, String propertyName,
Object value) {
Class clazz = bean.getClass();
try {
Field field = clazz.getDeclaredField(propertyName);
Method method = clazz.getDeclaredMethod(getSetterName(field
.getName()), new Class[] { field.getType() });
return method.invoke(bean, new Object[] { value });
} catch (Exception e) {
}
return null;
}
// 反射調(diào)用getter方法,得到field的值
private static Object getProperty(Object bean, String propertyName) {
Class clazz = bean.getClass();
try {
Field field = clazz.getDeclaredField(propertyName);
Method method = clazz.getDeclaredMethod(getGetterName(field
.getName()), new Class[] {});
return method.invoke(bean, new Object[] {});
} catch (Exception e) {
}
return null;
}
// 根據(jù)field名,得到getter方法名
private static String getGetterName(String propertyName) {
String method = "get" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
return method;
}
// 根據(jù)field名,得到setter方法名
private static String getSetterName(String propertyName) {
String method = "set" + propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
return method;
}
}
class Person {
private String name;
private int age;
private String address;
// 用于測(cè)試深層克隆
private Person father;
private String array[] = null;
public Person() {
}
public Person(String name, int age, String address) {
this.name = name;
this.address = address;
this.age = age;
}
public Person(String name, int age, String address, Person father) {
this.name = name;
this.address = address;
this.age = age;
this.father = father;
}
// 所有的getter方法和setter方法要求都是public,且具有一定的命名規(guī)則
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person getFather() {
return father;
}
public void setFather(Person father) {
this.father = father;
}
public String toString() {
String sum = "";
for (String s : array) {
sum += " " + s;
}
return "{Name=" + name + ",Age=" + age + ",Address=" + address + sum
+ "}";
}
public String[] getArray() {
return array;
}
public void setArray(String[] array) {
this.array = array;
}
}