package test1; import java.util.Date; import java.util.GregorianCalendar; public class CloneTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { Employee original = new Employee("john Q. Public",5000); original.setHireDay(2000, 1, 1); Employee copy = original.clone(); copy.raiseSalary(10); copy.setHireDay(2002, 12, 31); System.out.println("original=" + original); System.out.println("copy=" + copy); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } class Employee implements Cloneable{ private String name; private double salary; private Date hireDay; public Employee(String n,double s){ name = n; salary = s; hireDay = new Date(); } public Employee clone() throws CloneNotSupportedException{ Employee cloned = (Employee) super.clone(); cloned.hireDay = (Date) hireDay.clone(); return cloned; } public void setHireDay(int year,int month,int day){ Date newHireDay = new GregorianCalendar(year,month-1,day).getTime(); hireDay.setTime(newHireDay.getTime()); } public void raiseSalary(double byPercent){ double raise = salary * byPercent /100; salary += raise; } public String toString(){ return "Employee[name="+name+",salary="+salary+",hireDay="+hireDay+"]"; } }
輸出結果:
original=Employee[name=john Q. Public,salary=5000.0,hireDay=Sat Jan 01 00:00:00 CST 2000]
copy=Employee[name=john Q. Public,salary=5500.0,hireDay=Tue Dec 31 00:00:00 CST 2002]
學習小結:
在對各個域進行對應的拷貝時,如果對象中包含了子對象的引用,拷貝的結果會是的兩個域引用同一個子對象
因此原始對象與拷貝對象共享這部分信息。若這部分信息不會發生改變時,則進行淺拷貝(默認拷貝)即可,但是
如果這部分信息會發生改變,那麼需要進行深拷貝,以防止一個對象對這部分信息的修改影響了另一個對象。
拷貝時:
1.實現Cloneable接口
2.使用public訪問修飾符重新定義clone方法
3.實現深拷貝的時候必須克隆所有可變域的實例域(如上代碼中的hireDay域)