// file: TestCopier.java // author: Robert Keller // purpose: To demonstrate the Copier.maybeClone method. // Also, to illustrate cloning and // the distinctions between equals and ==. /** * ClassC implements cloneable, therefore method clone() is supported. */ class ClassC implements Cloneable { private static int counter = 0; // counts number of objects created in class C String name; // the name of an object in class C int serial; // the serial number of an object in class C /** Create an object in class C with name x. */ ClassC(String x) { name = x; serial = ++counter; } /** Create a new object that is a clone of this. */ public Object clone() { ClassC cl = new ClassC(name); // The clone has the same name as original. cl.serial = this.serial; // The clone even has same serial as original. return cl; // However, the counter still got incremented. } /** Return a String representation of this object. */ public String toString() { return name + "#" + serial; } /** Test this object for contents equal to other */ public boolean equals(Object other) { return toString().equals(other.toString()); } /** Return the number of objects constructed in this class. */ static public int getCount() { return counter; } } /** * ClassD does not implement cloneable, * therefore method clone() is not supported. */ class ClassD { private static int counter = 0; // counts number of objects created in class D String name; // the name of an object in class D int serial; // the serial number of an object in class D /** Create an object in class D with name x. */ ClassD(String x) { name = x; serial = ++counter; } /** Return a String representation of this object. */ public String toString() { return name + "#" + serial; } /** Test this object for contents equal to other */ public boolean equals(Object other) { return toString().equals(other.toString()); } /** Return the number of objects constructed in this class. */ static public int getCount() { return counter; } } /** * TestCopier provides a main method for testing Copier.maybeClone */ class TestCopier { public static void main(String arg[]) { // Make cloneable object, copy it, and show the result of == and equals tests. ClassC c = new ClassC("c"); System.out.println("Using Copier.maybeClone to copy a cloneable object"); Object cCopy = Copier.maybeClone(c); System.out.println("c = " + c); System.out.println("cCopy = " + cCopy); System.out.println("c == cCopy ==> " + (c == cCopy)); System.out.println("c.equals(cCopy) ==> " + (c.equals(cCopy))); System.out.println("As cCopy is a clone of C, " + "we expect them to be equals but not ==."); System.out.println(); // Make non-cloneable object, copy it, and show the result of == and // equals tests. ClassD d = new ClassD("D"); System.out.println("Using Copier.maybeClone to copy a non-cloneable object"); Object dCopy = Copier.maybeClone(d); System.out.println("d = " + d); System.out.println("dCopy = " + dCopy); System.out.println("d == dCopy ==> " + (d == dCopy)); System.out.println("d.equals(dCopy) ==> " + (d.equals(dCopy))); System.out.println("As d is not cloneable, " + "dCopy is just another name for d."); System.out.println(); System.out.println(ClassC.getCount() + " members of ClassC were created."); System.out.println(ClassD.getCount() + " members of ClassD were created."); } } /* Output: Using Copier.maybeClone to copy a cloneable object c = c#1 cCopy = c#1 c == cCopy ==> false c.equals(cCopy) ==> true As cCopy is a clone of C, we expect them to be equals but not ==. Using Copier.maybeClone to copy a non-cloneable object d = D#1 dCopy = D#1 d == dCopy ==> true d.equals(dCopy) ==> true As d is not cloneable, dCopy is just another name for d. 2 members of ClassC were created. 1 members of ClassD were created. */