例1:
/**
@version 1.0 2008-10-9
@author zzg
用于试验clone方法及Cloneable接口,用到2个类。
父类Employee,父类的对象实例域hireDay
子类Manager,子类的对象实例域dutyDay
Cloneable是接口标识,它并未定义任何方法。
*/
import java.util.*;
public class CloneTest {
public static void main(String[] args) {
try {
/*
* 1) clone
* 方法必须是public的,否则只能在本类或子类中调用,因Object对象中的clone方法是protected的。
* 注:请确保父类的clone方法未被注释 试验:请尝试注释掉父类中的clone方法,观察语句:Employee copy =
* original.clone();
*/
Employee original = new Employee("John", 50000);
original.setHireDay(2000, 1, 1);
Employee copy = original.clone();
copy.raiseSalary(10);
copy.changeHireDay(2002, 12, 31);
System.out.println("original=" + original);
System.out.println("copy=" + copy);
/*
* 2)如果父类实现了clone方法,子类未实现clone方法,则无法用子类对象在CloneTest类中调用,见3)中试验。
* 而只能将子类对象转换为父类对象,再调用clone。 注:请首先注释掉子类中的clone方法
*/
// Manager original2 = new Manager("John", 50000);
// original2.setBonus(10.0);
// original2.setHireDay(2000, 1, 1);
// original2.setDutyDay(2000, 11, 3);
// Employee original=original2;
// Employee copy = original.clone();
// Manager copy2=(Manager)copy;
// copy2.setBonus(11.0);
// copy2.raiseSalary(10);
// copy2.changeHireDay(2002, 12, 31);
// copy2.changeDutyDay(2003, 11, 3);
// System.out.println("original2=" + original2);
// System.out.println("copy2=" + copy2);
/*
* 3)父类clone方法解决父类中对象实例域的复制,子类clone方法解决子类中对象实例域的复制。
* 注:请确保子类、父类中的clone方法均未被注释掉 试验:请尝试注释掉子类的clone,观察语句:Manager copy2 =
* original2.clone();
*/
// Manager original2 = new Manager("John", 50000);
// original2.setHireDay(2000, 1, 1);
// original2.setDutyDay(2000, 11, 3);
// Manager copy2 = original2.clone();
// copy2.raiseSalary(10);
// copy2.changeHireDay(2002, 12, 31);
// copy2.changeDutyDay(2003, 11, 3);
// System.out.println("original2=" + original2);
// System.out.println("copy2=" + copy2);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
class Employee implements Cloneable {
public Employee(String n, double s) {
name = n;
salary = s;
}
public Employee clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
// clone mutable fields
cloned.hireDay = (Date) hireDay.clone();
return cloned;
}
public void setHireDay(int year, int month, int day) {
hireDay = new GregorianCalendar(year, month - 1, day).getTime();
}
public void changeHireDay(int year, int month, int day) {
hireDay.setYear(year - 1900);
hireDay.setMonth(month - 1);
hireDay.setDate(day);
}
public void raiseSalary(double byPercent) {
double raise = salary * byPercent / 100;
salary += raise;
}
public String toString() {
return "Employee[name=" + name + ",salary=" + salary + ",hireDay="
+ hireDay + "]";
}
private String name;
private double salary;
private Date hireDay;
}
class Manager extends Employee {
public Manager(String n, double s) {
super(n, s);
bonus = 0;
}
public void setBonus(double b) {
bonus = b;
}
public Manager clone() throws CloneNotSupportedException {
Manager cloned = (Manager) super.clone();
// clone mutable fields
cloned.dutyDay = (Date) dutyDay.clone();
return cloned;
}
public void setDutyDay(int year, int month, int day) {
dutyDay = new GregorianCalendar(year, month - 1, day).getTime();
}
public void changeDutyDay(int year, int month, int day) {
dutyDay.setYear(year - 1900);
dutyDay.setMonth(month - 1);
dutyDay.setDate(day);
}
public String toString() {
return super.toString() + "bonus=" + bonus + ",DutyDay=" + dutyDay;
}
private double bonus;
private Date dutyDay;
}
*****************************************************************************
例2:
import java.util.Date;
/**
* @version 1.0 2008-10-9
* @author zzg 用于试验数组clone。 通过本例,可见数组实例域与对象实例域十分类似,注意clone。
*/
public class ArrayCloneTest {
private int[] a;
private int[] b; // 简单类型数组,仅需浅clone
private Date[] d; // 对象数组,需深clone
public int[] getA() {
return a;
}
public void setA(int[] a) {
this.a = a;
}
public int[] getB() { // 浅clone
return b.clone();
}
public void setB(int[] b) {
this.b = b.clone();
}
public Date[] getD() { // 深clone,每个数组元素都要clone
Date[] temp;
temp = d.clone();
for (int i = 0; i < d.length; i++)
temp[i] = (Date) d[i].clone();
return temp;
}
public void setD(Date[] d) {
Date[] temp;
temp = d.clone();
for (int i = 0; i < d.length; i++)
temp[i] = (Date) d[i].clone();
this.d = temp;
}
public static void print(int[] ar) {
for (int i = 0; i < ar.length; i++)
System.out.println("" + ar[i]);
}
public static void main(String[] args) {
ArrayCloneTest act = new ArrayCloneTest();
int[] c = { 1, 2, 3 };
act.setA(c);
act.setB(c);
System.out.println("---------A1----------");
ArrayCloneTest.print(act.getA());
System.out.println("---------B1----------");
ArrayCloneTest.print(act.getB());
System.out.println("---------C1----------");
ArrayCloneTest.print(c);
/*
* 修改c,影响a,但不影响b
*/
c[2] = 4;
System.out.println("---------A2----------");
ArrayCloneTest.print(act.getA());
System.out.println("---------B2----------");
ArrayCloneTest.print(act.getB());
System.out.println("---------C2----------");
ArrayCloneTest.print(c);
/*
* 修改a,影响c;但修改b,不影响c。
*/
act.getA()[2] = 5;
act.getB()[2] = 5;
System.out.println("---------A3----------");
ArrayCloneTest.print(act.getA());
System.out.println("---------B3----------");
ArrayCloneTest.print(act.getB());
System.out.println("---------C3----------");
ArrayCloneTest.print(c);
}
}