浅度克隆
先定义一个克隆的抽象类,专门负责克隆:
package com.xs.object;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public abstract class AClone {
protected Object myClone() {
String className = this.getClass().getName();
Class<?> clazz = null;
Object object = null;
try {
clazz = Class.forName(className);
object = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
String getMethodName = "get" +
fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Method getMethod = clazz.getMethod(getMethodName);
Object value = getMethod.invoke(this);
String setMethodName = "set" +
fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Class<?> type = field.getType();
Method setMethod = clazz.getMethod(setMethodName, type);
setMethod.invoke(object, value);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return object;
}
}
定义需要被复制的类,并且继承上面的抽象类:
class MyUser extends AClone{
private String username;
private String password;
private BirthDay birthday;
public MyUser() {}
public MyUser(String username, String password, BirthDay birthday) {
this.username = username;
this.password = password;
this.birthday = birthday;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public BirthDay getBirthday() {
return birthday;
}
public void setBirthday(BirthDay birthday) {
this.birthday = birthday;
}
public MyUser myClone(){
Object o = null;
o = super.myClone();
return (MyUser) o;
}
public String toString(){
return username + "|" + password + "|" + birthday;
}
}
定义BirthDay:
class BirthDay{
private int year;
private int month;
private int day;
public BirthDay() {}
public BirthDay(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getMonth() {
return month;
}
public void setMonth(int month) {
this.month = month;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String toString(){
return year + "年" + month + "月" + day + "日";
}
}
测试:
public class MyCloneTest {
public static void main(String[] args){
MyUser user = new MyUser("Tom", "123", new BirthDay(2014, 1, 1));
MyUser userClone = user.myClone();
userClone.setUsername("Jim");
BirthDay birthDay = userClone.getBirthday();
birthDay.setDay(10);
System.out.println("prototype:" + user);
System.out.println(" clone:" + userClone);
}
}
输出:
prototype:Tom|123|2014年1月10日
clone:Jim|123|2014年1月10日
我们可以看到,改变克隆后对象的出生日期,原来对象的出生日期也改变了,这里只实现了浅度复制。
深度克隆
实现深度克隆只需要做小小的改动
1.让类BirthDay实现抽象类AClone。
2.修改类MyUser的myClone方法:
public MyUser myClone(){
MyUser o = null;
o = (MyUser) super.myClone();
BirthDay birthDay = o.getBirthday();
BirthDay cloneBirthDay = (BirthDay) birthDay.myClone();
o.setBirthday(cloneBirthDay);
return o;
}
测试输出:
prototype:Tom|123|2014年1月1日
clone:Jim|123|2014年1月10日
我们可以看到,原生对象的出生日期并没有改变,实现了深度克隆!