Java/Class/Clone

Материал из Java эксперт
Перейти к: навигация, поиск

A Cloning Example

   <source lang="java">
    

public class MainClass {

 public static void main(String[] args) {
   Employee emp1 = new Employee("M", "A");
   emp1.setSalary(40000.0);
   Employee emp2 = (Employee) emp1.clone();
   emp1.setLastName("Smith");
   System.out.println(emp1);
   System.out.println(emp2);
 }

} class Employee {

 private String lastName;
 private String firstName;
 private Double salary;
 public Employee(String lastName, String firstName) {
   this.lastName = lastName;
   this.firstName = firstName;
 }
 public String getLastName() {
   return this.lastName;
 }
 public void setLastName(String lastName) {
   this.lastName = lastName;
 }
 public String getFirstName() {
   return this.firstName;
 }
 public void setFirstName(String firstName) {
   this.firstName = firstName;
 }
 public Double getSalary() {
   return this.salary;
 }
 public void setSalary(Double salary) {
   this.salary = salary;
 }
 public Object clone() {
   Employee emp;
   emp = new Employee(this.lastName, this.firstName);
   emp.setSalary(this.salary);
   return emp;
 }
 public String toString() {
   return this.getClass().getName() + "[" + this.firstName + " " + this.lastName + ", "
       + this.salary + "]";
 }

}



 </source>
   
  
 
  



A collection of utilities to workaround limitations of Java clone framework

   <source lang="java">
 

/*

* $HeadURL$
* $Revision$
* $Date$
*
* 
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
* 
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/

import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;

/**

* A collection of utilities to workaround limitations of Java clone framework.
*/

public class CloneUtils {

   public static Object clone(final Object obj) throws CloneNotSupportedException {
       if (obj == null) {
           return null;
       }
       if (obj instanceof Cloneable) {
           Class<?> clazz = obj.getClass ();
           Method m;
           try {
               m = clazz.getMethod("clone", (Class[]) null);
           } catch (NoSuchMethodException ex) {
               throw new NoSuchMethodError(ex.getMessage());
           }
           try {
               return m.invoke(obj, (Object []) null);
           } catch (InvocationTargetException ex) {
               Throwable cause = ex.getCause();
               if (cause instanceof CloneNotSupportedException) {
                   throw ((CloneNotSupportedException) cause); 
               } else {
                   throw new Error("Unexpected exception", cause);
               }
           } catch (IllegalAccessException ex) {
               throw new IllegalAccessError(ex.getMessage());
           }
       } else {
           throw new CloneNotSupportedException();
       }
   }
   
   /**
    * This class should not be instantiated.
    */
   private CloneUtils() {
   }

}


 </source>
   
  
 
  



Arrays are automatically cloneable

   <source lang="java">
  

public class Main {

 public static void main(String[] argv) throws Exception {
   int[] ints = new int[] { 123, 234 };
   int[] intsClone = (int[]) ints.clone();
 }

}


 </source>
   
  
 
  



Checking to see if a reference can be cloned

   <source lang="java">
   

// : appendixa:CheckCloneable.java // Checking to see if a reference can be cloned. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. // Can"t clone this because it doesn"t override clone(): class Ordinary { } // Overrides clone, but doesn"t implement Cloneable: class WrongClone extends Ordinary {

 public Object clone() throws CloneNotSupportedException {
   return super.clone(); // Throws exception
 }

} // Does all the right things for cloning: class IsCloneable extends Ordinary implements Cloneable {

 public Object clone() throws CloneNotSupportedException {
   return super.clone();
 }

} // Turn off cloning by throwing the exception: class NoMore extends IsCloneable {

 public Object clone() throws CloneNotSupportedException {
   throw new CloneNotSupportedException();
 }

} class TryMore extends NoMore {

 public Object clone() throws CloneNotSupportedException {
   // Calls NoMore.clone(), throws exception:
   return super.clone();
 }

} class BackOn extends NoMore {

 private BackOn duplicate(BackOn b) {
   // Somehow make a copy of b and return that copy.
   // This is a dummy copy, just to make the point:
   return new BackOn();
 }
 public Object clone() {
   // Doesn"t call NoMore.clone():
   return duplicate(this);
 }

} // You can"t inherit from this, so you can"t override // the clone method as you can in BackOn: final class ReallyNoMore extends NoMore { } public class CheckCloneable {

 public static Ordinary tryToClone(Ordinary ord) {
   String id = ord.getClass().getName();
   System.out.println("Attempting " + id);
   Ordinary x = null;
   if (ord instanceof Cloneable) {
     try {
       x = (Ordinary) ((IsCloneable) ord).clone();
       System.out.println("Cloned " + id);
     } catch (CloneNotSupportedException e) {
       System.err.println("Could not clone " + id);
     }
   } else {
     System.out.println("Doesn"t implement Cloneable");
   }
   return x;
 }
 public static void main(String[] args) {
   // Upcasting:
   Ordinary[] ord = { new IsCloneable(), new WrongClone(), new NoMore(),
       new TryMore(), new BackOn(), new ReallyNoMore(), };
   Ordinary x = new Ordinary();
   // This won"t compile; clone() is protected in Object:
   //! x = (Ordinary)x.clone();
   // Checks first to see if a class implements Cloneable:
   for (int i = 0; i < ord.length; i++)
     tryToClone(ord[i]);
 }

} ///:~




 </source>
   
  
 
  



Class is declared to be cloneable.

   <source lang="java">
  

class Employee implements Cloneable {

 String name;
 int salary;
 public Employee(String name, int salary) {
   this.name = name;
   this.salary = salary;
 }
 public Employee() {
 }
 public String getName() {
   return name;
 }
 public void setName(String name) {
   this.name = name;
 }
 public void setSalary(int salary) {
   this.salary = salary;
 }
 public int getSalary() {
   return this.salary;
 }
 public Object clone() throws CloneNotSupportedException {
   try {
     return super.clone();
   } catch (CloneNotSupportedException cnse) {
     System.out.println("CloneNotSupportedException thrown " + cnse);
     throw new CloneNotSupportedException();
   }
 }

} public class Main {

 public static void main(String[] args) {
   try {
     Employee e = new Employee("Dolly", 1000);
     System.out.println(e);
     System.out.println("The employee"s name is " + e.getName());
     System.out.println("The employees"s pay is " + e.getSalary());
     Employee eClone = (Employee) e.clone();
     System.out.println(eClone);
     System.out.println("The clone"s name is " + eClone.getName());
     System.out.println("The clones"s pay is " + eClone.getSalary());
   } catch (CloneNotSupportedException cnse) {
     System.out.println("Clone not supported");
   }
 }

}


 </source>
   
  
 
  



Clone an object with clone method from parent

   <source lang="java">
  

public class Main {

 public static void main(String[] args) {
   try {
     Employee e = new Employee("Dolly", 1000);
     System.out.println(e);
     System.out.println("The employee"s name is " + e.getName());
     System.out.println("The employees"s pay is " + e.getSalary());
     Employee eClone = (Employee) e.clone();
     System.out.println(eClone);
     System.out.println("The clone"s name is " + eClone.getName());
     System.out.println("The clones"s pay is " + eClone.getSalary());
     eClone.setName("Polly");
     eClone.setSalary(2000);
     System.out.println("The employee"s name is " + e.getName());
     System.out.println("The employees"s pay is " + e.getSalary());
     System.out.println("The clone"s name is " + eClone.getName());
     System.out.println("The clones"s pay is " + eClone.getSalary());
   } catch (Exception e) {
     System.out.println("Exception " + e);
   }
 }

} class Employee implements Cloneable {

 private StringBuffer name;
 private int salary;
 public Employee(String name, int salary) {
   this.name = new StringBuffer(name);
   this.salary = salary;
 }
 public Employee() {
 }
 public Object clone() throws CloneNotSupportedException {
   try {
     return super.clone();
   } catch (CloneNotSupportedException cnse) {
     System.out.println("CloneNotSupportedException thrown " + cnse);
     throw new CloneNotSupportedException();
   }
 }
 public String getName() {
   return name.toString();
 }
 public void setName(String name) {
   this.name.delete(0, this.name.length());
   this.name.append(name);
 }
 public void setSalary(int salary) {
   this.salary = salary;
 }
 public int getSalary() {
   return this.salary;
 }

}


 </source>
   
  
 
  



Clone demo

   <source lang="java">
   

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* 
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java 
* language and environment is gratefully acknowledged.
* 
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/

class One extends java.lang.Object {

 int x;

} class Two extends One /*implements Cloneable*/ {

 int y;
 public void foo() {
   try {
     Object o = this.clone();
   } catch (CloneNotSupportedException ex) {
     System.err.println(ex);
   }
 }
 public Object clone() throws CloneNotSupportedException {
   return super.clone();
 }

} public class CloneSub {

 public static void main(String[] args) throws CloneNotSupportedException {
   Two t1 = new Two();
   t1.x = 100;
   t1.y = 200;
   Two t2 = (Two)t1.clone();
   System.out.println(t2);
   System.out.println(t2.y);
 }

}




 </source>
   
  
 
  



Clone objects

   <source lang="java">
   

public class Main {

 public static void main(String[] args) {
   Person person1 = new Person();
   person1.setFirstName("F");
   person1.setLastName("L");
   Person person2 = (Person) person1.clone();
   Person person3 = (Person) person2.clone();
   System.out.println("Person 1: " + person1.getFirstName() + " " + person1.getLastName());
   System.out.println("Person 2: " + person2.getFirstName() + " " + person2.getLastName());
   System.out.println("Person 3: " + person3.getFirstName() + " " + person3.getLastName());
 }

} class Person implements Cloneable {

 private String firstName;
 private String lastName;
 public Object clone() {
   Person obj = new Person();
   obj.setFirstName(this.firstName);
   obj.setLastName(this.lastName);
   return obj;
 }
 public String getFirstName() {
   return firstName;
 }
 public void setFirstName(String firstName) {
   this.firstName = firstName;
 }
 public String getLastName() {
   return lastName;
 }
 public void setLastName(String lastName) {
   this.lastName = lastName;
 }

} /* Person 1: F L Person 2: F L Person 3: F L

  • /



 </source>
   
  
 
  



Clone Via Serialization

   <source lang="java">

/**

* 
* The ObjectStyle Group Software License, version 1.1
* ObjectStyle Group - http://objectstyle.org/
* 
* Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
* of the software. All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
* 
* 3. The end-user documentation included with the redistribution, if any,
*    must include the following acknowlegement:
*    "This product includes software developed by independent contributors
*    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
* 
* 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
*    or promote products derived from this software without prior written
*    permission. For written permission, email
*    "andrus at objectstyle dot org".
* 
* 5. Products derived from this software may not be called "ObjectStyle"
*    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
*    names without prior written permission.
* 
* THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* 
* 
* This software consists of voluntary contributions made by many
* individuals and hosted on ObjectStyle Group web site.  For more
* information on the ObjectStyle Group, please see
* <http://objectstyle.org/>.
*/

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import java.lang.reflect.Member; import java.lang.reflect.Modifier; import java.net.URL; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.ruparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException; import org.xml.sax.XMLReader; /**

* Contains various unorganized static utility methods used across Cayenne.
* 
* @author Andrei Adamchik
*/

public class Util {

 /**
  * Creates Serializable object copy using serialization/deserialization.
  */
 public static Object cloneViaSerialization(Serializable obj) throws Exception {
     ByteArrayOutputStream bytes = new ByteArrayOutputStream() {
         public synchronized byte[] toByteArray() {
             return buf;
         }
     };
     ObjectOutputStream out = new ObjectOutputStream(bytes);
     out.writeObject(obj);
     out.close();
     ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes
             .toByteArray()));
     Object objCopy = in.readObject();
     // no need to close the stream - we created it and now will be throwing away...
     // in.close();
     
     return objCopy;
 }

}

 </source>
   
  
 
  



Cloning a composed object

   <source lang="java">
   

// : appendixa:DeepCopy.java // Cloning a composed object. // {Depends: junit.jar} // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import junit.framework.*; class DepthReading implements Cloneable {

 private double depth;
 public DepthReading(double depth) {
   this.depth = depth;
 }
 public Object clone() {
   Object o = null;
   try {
     o = super.clone();
   } catch (CloneNotSupportedException e) {
     e.printStackTrace();
   }
   return o;
 }
 public double getDepth() {
   return depth;
 }
 public void setDepth(double depth) {
   this.depth = depth;
 }
 public String toString() {
   return String.valueOf(depth);
 }

} class TemperatureReading implements Cloneable {

 private long time;
 private double temperature;
 public TemperatureReading(double temperature) {
   time = System.currentTimeMillis();
   this.temperature = temperature;
 }
 public Object clone() {
   Object o = null;
   try {
     o = super.clone();
   } catch (CloneNotSupportedException e) {
     e.printStackTrace();
   }
   return o;
 }
 public double getTemperature() {
   return temperature;
 }
 public void setTemperature(double temperature) {
   this.temperature = temperature;
 }
 public String toString() {
   return String.valueOf(temperature);
 }

} class OceanReading implements Cloneable {

 private DepthReading depth;
 private TemperatureReading temperature;
 public OceanReading(double tdata, double ddata) {
   temperature = new TemperatureReading(tdata);
   depth = new DepthReading(ddata);
 }
 public Object clone() {
   OceanReading o = null;
   try {
     o = (OceanReading) super.clone();
   } catch (CloneNotSupportedException e) {
     e.printStackTrace();
   }
   // Must clone references:
   o.depth = (DepthReading) o.depth.clone();
   o.temperature = (TemperatureReading) o.temperature.clone();
   return o; // Upcasts back to Object
 }
 public TemperatureReading getTemperatureReading() {
   return temperature;
 }
 public void setTemperatureReading(TemperatureReading tr) {
   temperature = tr;
 }
 public DepthReading getDepthReading() {
   return depth;
 }
 public void setDepthReading(DepthReading dr) {
   this.depth = dr;
 }
 public String toString() {
   return "temperature: " + temperature + ", depth: " + depth;
 }

} public class DeepCopy extends TestCase {

 public DeepCopy(String name) {
   super(name);
 }
 public void testClone() {
   OceanReading reading = new OceanReading(33.9, 100.5);
   // Now clone it:
   OceanReading clone = (OceanReading) reading.clone();
   TemperatureReading tr = clone.getTemperatureReading();
   tr.setTemperature(tr.getTemperature() + 1);
   clone.setTemperatureReading(tr);
   DepthReading dr = clone.getDepthReading();
   dr.setDepth(dr.getDepth() + 1);
   clone.setDepthReading(dr);
   assertEquals(reading.toString(), "temperature: 33.9, depth: 100.5");
   assertEquals(clone.toString(), "temperature: 34.9, depth: 101.5");
 }
 public static void main(String[] args) {
   junit.textui.TestRunner.run(DeepCopy.class);
 }

} ///:~




 </source>
   
  
 
  



Creating a Deep Copy

   <source lang="java">
    

public class MainClass {

 public static void main(String[] args) {
   Employee emp1 = new Employee("M", "A");
   emp1.setSalary(40000.0);
   emp1.address = new Address("First Street", "San F", "CA", "93702");
   Employee emp2 = (Employee) emp1.clone();
   printEmployee(emp1);
   printEmployee(emp2);
   emp2.setLastName("Smith");
   emp2.address = new Address("Street", "B", "CA", "93722");
   printEmployee(emp1);
   printEmployee(emp2);
 }
 private static void printEmployee(Employee e) {
   System.out.println(e.getFirstName() + " " + e.getLastName());
   System.out.println(e.address.getAddress());
   System.out.println("Salary: " + e.getSalary());
 }

} class Employee implements Cloneable {

 private String lastName;
 private String firstName;
 private Double salary;
 public Address address;
 public Employee(String lastName, String firstName) {
   this.lastName = lastName;
   this.firstName = firstName;
   this.address = new Address();
 }
 public String getLastName() {
   return this.lastName;
 }
 public void setLastName(String lastName) {
   this.lastName = lastName;
 }
 public String getFirstName() {
   return this.firstName;
 }
 public void setFirstName(String firstName) {
   this.firstName = firstName;
 }
 public Double getSalary() {
   return this.salary;
 }
 public void setSalary(Double salary) {
   this.salary = salary;
 }
 public Object clone() {
   Employee emp;
   try {
     emp = (Employee) super.clone();
     emp.address = (Address) address.clone();
   } catch (CloneNotSupportedException e) {
     return null; // will never happen
   }
   return emp;
 }
 public String toString() {
   return this.getClass().getName() + "[" + this.firstName + " " + this.lastName + ", "
       + this.salary + "]";
 }

} class Address implements Cloneable {

 private String street;
 private String city;
 private String state;
 private String zipCode;
 public Address() {
   this.street = "";
   this.city = "";
   this.state = "";
   this.zipCode = "";
 }
 public Address(String street, String city, String state, String zipCode) {
   this.street = street;
   this.city = city;
   this.state = state;
   this.zipCode = zipCode;
 }
 public Object clone(){
   try {
     return super.clone();
   } catch (CloneNotSupportedException e) {
     return null; // will never happen
   }
 }
 public String getAddress() {
   return this.street + "\n" + this.city + ", " + this.state + " " + this.zipCode;
 }

}



 </source>
   
  
 
  



Creating local copies with clone

   <source lang="java">
   

// : appendixa:LocalCopy.java // Creating local copies with clone(). // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.

class MyObject implements Cloneable {

 private int n;
 public MyObject(int n) {
   this.n = n;
 }
 public Object clone() {
   Object o = null;
   try {
     o = super.clone();
   } catch (CloneNotSupportedException e) {
     System.err.println("MyObject can"t clone");
   }
   return o;
 }
 public int getValue() {
   return n;
 }
 public void setValue(int n) {
   this.n = n;
 }
 public void increment() {
   n++;
 }
 public String toString() {
   return Integer.toString(n);
 }

} public class LocalCopy {

 public static MyObject g(MyObject v) {
   // Passing a reference, modifies outside object:
   v.increment();
   return v;
 }
 public static MyObject f(MyObject v) {
   v = (MyObject) v.clone(); // Local copy
   v.increment();
   return v;
 }
 public static void main(String[] args) {
   MyObject a = new MyObject(11);
   MyObject b = g(a);
   // Reference equivalence, not object equivalence:
   System.out.println("a == b: " + (a == b) + "\na = " + a + "\nb = " + b);
   MyObject c = new MyObject(47);
   MyObject d = f(c);
   System.out.println("c == d: " + (c == d) + "\nc = " + c + "\nd = " + d);
 }

} ///:~




 </source>
   
  
 
  



Deep clone Object

   <source lang="java">

/*

* Copyright (C) 2001-2003 Colin Bell
* colbell@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.io.*; import java.text.NumberFormat; import java.util.regex.Matcher; import java.util.regex.Pattern; /**

* General purpose utilities functions.
*
* @author 
*/

public class Utilities {

 /**
  * Creates a clone of any serializable object. Collections and arrays
  * may be cloned if the entries are serializable.
  *
  * Caution super class members are not cloned if a super class is not serializable.
  */
 public static Object cloneObject(Object toClone, final ClassLoader classLoader)
 {
    if(null == toClone)
    {
       return null;
    }
    else
    {
       try
       {
          ByteArrayOutputStream bOut = new ByteArrayOutputStream();
          ObjectOutputStream oOut = new ObjectOutputStream(bOut);
          oOut.writeObject(toClone);
          oOut.close();
          ByteArrayInputStream bIn = new ByteArrayInputStream(bOut.toByteArray());
          bOut.close();
          ObjectInputStream oIn = new ObjectInputStream(bIn)
          {
             protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException
             {
               return Class.forName(desc.getName(), false, classLoader);
             }
          };
          bIn.close();
          Object copy = oIn.readObject();
          oIn.close();
          return copy;
       }
       catch (Exception e)
       {
          throw new RuntimeException(e);
       }
    }
 }

}

 </source>
   
  
 
  



Deep clone serializing/de-serializng Clone

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /**

* Utility for object cloning
* 
* @author 
*/

public class CloneUtil {

   /**
    * Provides a deep clone serializing/de-serializng objToClone     
    * 
    * @param objToClone The object to be cloned
    * @return The cloned object
    */
   public static final Object deepClone(Object objToClone)
   {
       try
       {
           ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(100);
           ObjectOutputStream objectoutputstream = new ObjectOutputStream(bytearrayoutputstream);
           objectoutputstream.writeObject(objToClone);
           byte abyte0[] = bytearrayoutputstream.toByteArray();
           objectoutputstream.close();
           ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(abyte0);
           ObjectInputStream objectinputstream = new ObjectInputStream(bytearrayinputstream);
           Object clone = objectinputstream.readObject();
           objectinputstream.close();
           return clone;
       }
       catch (Exception exception)
       {
           // nothing
       }
       return null;
   }

}


 </source>
   
  
 
  



Deep Copy Test

   <source lang="java">
   

/* Correct Output: Original (orginal values): Person-A - Civic Clone (before change): Person-A - Civic Clone (after change): Person-B - Accord Original (after clone is modified): Person-A - Civic

  • /

/* Software Architecture Design Patterns in Java by Partha Kuchana Auerbach Publications

  • /

class Person implements Cloneable {

 //Lower-level object
 private Car car;
 private String name;
 public Car getCar() {
   return car;
 }
 public String getName() {
   return name;
 }
 public void setName(String s) {
   name = s;
 }
 public Person(String s, String t) {
   name = s;
   car = new Car(t);
 }
 public Object clone() {
   //Deep copy
   Person p = new Person(name, car.getName());
   return p;
 }

} class Car {

 private String name;
 public String getName() {
   return name;
 }
 public void setName(String s) {
   name = s;
 }
 public Car(String s) {
   name = s;
 }

} public class DeepCopyTest {

 public static void main(String[] args) {
   //Original Object
   Person p = new Person("Person-A", "Civic");
   System.out.println("Original (orginal values): " + p.getName() + " - "
       + p.getCar().getName());
   //Clone as a shallow copy
   Person q = (Person) p.clone();
   System.out.println("Clone (before change): " + q.getName() + " - "
       + q.getCar().getName());
   //change the primitive member
   q.setName("Person-B");
   //change the lower-level object
   q.getCar().setName("Accord");
   System.out.println("Clone (after change): " + q.getName() + " - "
       + q.getCar().getName());
   System.out.println("Original (after clone is modified): " + p.getName()
       + " - " + p.getCar().getName());
 }

}



 </source>
   
  
 
  



Demonstration of cloning

   <source lang="java">
   

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* 
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java 
* language and environment is gratefully acknowledged.
* 
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/

/** Demonstration of cloning. */ public class Clone1 implements Cloneable {

 /** Clone this object. Call super.clone() to do the work */
 public Object clone() {
   try {
     return super.clone();
   } catch (CloneNotSupportedException ex) {
     System.out.println("Now that"s a surprise!!");
     throw new InternalError(ex.toString());
   }
 }
 int x;
 transient int y;  // will be cloned, but not serialized
 /** Display the current object as a string */
 public String toString() {
   return "Clone1[" + x + "," + y + "]";
 }

}




 </source>
   
  
 
  



Go through a few gyrations to add cloning to your own class

   <source lang="java">
   

// : appendixa:AddingClone.java // You must go through a few gyrations // to add cloning to your own class. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.util.ArrayList; import java.util.Iterator; class Int2 implements Cloneable {

 private int i;
 public Int2(int ii) {
   i = ii;
 }
 public void increment() {
   i++;
 }
 public String toString() {
   return Integer.toString(i);
 }
 public Object clone() {
   Object o = null;
   try {
     o = super.clone();
   } catch (CloneNotSupportedException e) {
     System.err.println("Int2 can"t clone");
   }
   return o;
 }

} // Inheritance doesn"t remove cloneability: class Int3 extends Int2 {

 private int j; // Automatically duplicated
 public Int3(int i) {
   super(i);
 }

} public class AddingClone {

 public static void main(String[] args) {
   Int2 x = new Int2(10);
   Int2 x2 = (Int2) x.clone();
   x2.increment();
   System.out.println("x = " + x + ", x2 = " + x2);
   // Anything inherited is also cloneable:
   Int3 x3 = new Int3(7);
   x3 = (Int3) x3.clone();
   ArrayList v = new ArrayList();
   for (int i = 0; i < 10; i++)
     v.add(new Int2(i));
   System.out.println("v: " + v);
   ArrayList v2 = (ArrayList) v.clone();
   // Now clone each element:
   for (int i = 0; i < v.size(); i++)
     v2.set(i, ((Int2) v2.get(i)).clone());
   // Increment all v2"s elements:
   for (Iterator e = v2.iterator(); e.hasNext();)
     ((Int2) e.next()).increment();
   System.out.println("v2: " + v2);
   // See if it changed v"s elements:
   System.out.println("v: " + v);
 }

} ///:~




 </source>
   
  
 
  



Implements a pool of internalized objects

   <source lang="java">

/*

* Copyright 2007 (C) TJDO.
* All rights reserved.
*
* This software is distributed under the terms of the TJDO License version 1.0.
* See the terms of the TJDO License in the documentation provided with this software.
*
* $Id: InternPool.java,v 1.1 2007/11/30 19:42:26 jackknifebarber Exp $
*/

import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.AbstractCollection; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap;

/**

* Implements a pool of internalized objects.
* Used to implement pools that behave like the one used by String.intern().
*

* This implementation is synchronized. * It is a generic collection that is unmodifiable with the exception of the * {@link #intern} method. * * @author * @version $Revision: 1.1 $ */ public class InternPool extends AbstractCollection { private final Map pool = new WeakHashMap(); /** * Returns a canonical representation for the specified object. * <p> * This method behaves much like String.intern(). * A pool of objects, initially empty, is maintained privately. * <p> * If the pool already contains an object equal to the specified object as * determined by the equals(Object) method, then the object * from the pool is returned. * Otherwise, the specified object is added to the pool and a reference to * the specified object is returned. * <p> * It follows that for any two objects o1 and o2, * intern(o1) == intern(o2) is true * if and only if o1.equals(o2) is true. * * @param candidate * the object to internalize * * @return * an object that is equivalent to the specified object, but is * guaranteed to be from a pool of unique objects. */ public synchronized Object intern(Object candidate) { Reference ref = (Reference)pool.get(candidate); Object pooled = ref == null ? null : ref.get(); if (pooled == null) { pooled = candidate; pool.put(pooled, new WeakReference(pooled)); } return pooled; } public synchronized boolean contains(Object o) { return pool.containsKey(o); } public synchronized Iterator iterator() { return Collections.unmodifiableSet(pool.keySet()).iterator(); } public synchronized int size() { return pool.size(); } } </source>

Manipulate properties after clone operation

   <source lang="java">
  

public class Main {

 public static void main(String[] args) {
   try {
     Employee e = new Employee("B", 1000);
     System.out.println(e);
     System.out.println("The employee"s name is " + e.getName());
     System.out.println("The employees"s pay is " + e.getSalary());
     Employee eClone = (Employee) e.clone();
     System.out.println(eClone);
     System.out.println("The clone"s name is " + eClone.getName());
     System.out.println("The clones"s pay is " + eClone.getSalary());
     eClone.setName("A");
     eClone.setSalary(2000);
     System.out.println("The employee"s name is " + e.getName());
     System.out.println("The employees"s pay is " + e.getSalary());
     System.out.println("The clone"s name is " + eClone.getName());
     System.out.println("The clones"s pay is " + eClone.getSalary());
   } catch (Exception e) {
     System.out.println("Exception " + e);
   }
 }

} class Employee implements Cloneable {

 private StringBuffer name;
 private int salary;
 public Employee(String name, int salary) {
   this.name = new StringBuffer(name);
   this.salary = salary;
 }
 public Employee() {
 }
 public Object clone() throws CloneNotSupportedException {
   try {
     Employee o = (Employee) super.clone();
     o.name = new StringBuffer(name.toString());
     return o;
   } catch (CloneNotSupportedException cnse) {
     System.out.println("CloneNotSupportedException thrown " + cnse);
     throw new CloneNotSupportedException();
   }
 }
 public String getName() {
   return name.toString();
 }
 public void setName(String name) {
   this.name.delete(0, this.name.length());
   this.name.append(name);
 }
 public void setSalary(int salary) {
   this.salary = salary;
 }
 public int getSalary() {
   return this.salary;
 }

}


 </source>
   
  
 
  



Serializable and clone

   <source lang="java">
   

// : appendixa:Compete.java // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class Thing1 implements Serializable { } class Thing2 implements Serializable {

 Thing1 o1 = new Thing1();

} class Thing3 implements Cloneable {

 public Object clone() {
   Object o = null;
   try {
     o = super.clone();
   } catch (CloneNotSupportedException e) {
     System.err.println("Thing3 can"t clone");
   }
   return o;
 }

} class Thing4 implements Cloneable {

 private Thing3 o3 = new Thing3();
 public Object clone() {
   Thing4 o = null;
   try {
     o = (Thing4) super.clone();
   } catch (CloneNotSupportedException e) {
     System.err.println("Thing4 can"t clone");
   }
   // Clone the field, too:
   o.o3 = (Thing3) o3.clone();
   return o;
 }

} public class Compete {

 public static final int SIZE = 25000;
 public static void main(String[] args) throws Exception {
   Thing2[] a = new Thing2[SIZE];
   for (int i = 0; i < a.length; i++)
     a[i] = new Thing2();
   Thing4[] b = new Thing4[SIZE];
   for (int i = 0; i < b.length; i++)
     b[i] = new Thing4();
   long t1 = System.currentTimeMillis();
   ByteArrayOutputStream buf = new ByteArrayOutputStream();
   ObjectOutputStream o = new ObjectOutputStream(buf);
   for (int i = 0; i < a.length; i++)
     o.writeObject(a[i]);
   // Now get copies:
   ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
       buf.toByteArray()));
   Thing2[] c = new Thing2[SIZE];
   for (int i = 0; i < c.length; i++)
     c[i] = (Thing2) in.readObject();
   long t2 = System.currentTimeMillis();
   System.out.println("Duplication via serialization: " + (t2 - t1)
       + " Milliseconds");
   // Now try cloning:
   t1 = System.currentTimeMillis();
   Thing4[] d = new Thing4[SIZE];
   for (int i = 0; i < d.length; i++)
     d[i] = (Thing4) b[i].clone();
   t2 = System.currentTimeMillis();
   System.out.println("Duplication via cloning: " + (t2 - t1)
       + " Milliseconds");
 }

} ///:~




 </source>
   
  
 
  



Serializable Clone

   <source lang="java">

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public abstract class SerializableClone {

 public static Object clone(final Object obj) throws Exception {
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   ObjectOutputStream oout = new ObjectOutputStream(out);
   oout.writeObject(obj);
   ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(out.toByteArray()));
   return in.readObject();
 }

}

 </source>
   
  
 
  



Shallow Copy Test

   <source lang="java">
   

/* Software Architecture Design Patterns in Java by Partha Kuchana Auerbach Publications

  • /

class Person implements Cloneable {

 //Lower-level object
 private Car car;
 private String name;
 public Car getCar() {
   return car;
 }
 public String getName() {
   return name;
 }
 public void setName(String s) {
   name = s;
 }
 public Person(String s, String t) {
   name = s;
   car = new Car(t);
 }
 public Object clone() {
   //shallow copy
   try {
     return super.clone();
   } catch (CloneNotSupportedException e) {
     return null;
   }
 }

} class Car {

 private String name;
 public String getName() {
   return name;
 }
 public void setName(String s) {
   name = s;
 }
 public Car(String s) {
   name = s;
 }

} public class ShallowCopyTest {

 public static void main(String[] args) {
   //Original Object
   Person p = new Person("Person-A", "Civic");
   System.out.println("Original (orginal values): " + p.getName() + " - "
       + p.getCar().getName());
   //Clone as a shallow copy
   Person q = (Person) p.clone();
   System.out.println("Clone (before change): " + q.getName() + " - "
       + q.getCar().getName());
   //change the primitive member
   q.setName("Person-B");
   //change the lower-level object
   q.getCar().setName("Accord");
   System.out.println("Clone (after change): " + q.getName() + " - "
       + q.getCar().getName());
   System.out.println("Original (after clone is modified): " + p.getName()
       + " - " + p.getCar().getName());
 }

}



 </source>
   
  
 
  



Simple demo of avoiding side-effects by using Object.clone

   <source lang="java">
   

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* 
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java 
* language and environment is gratefully acknowledged.
* 
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/

import java.util.*; /**

* Simple demo of avoiding side-effects by using Object.clone()
* to duplicate an object before passing it to your enemy"s methods.
* Cloneable is a "marker" interface: it has no methods, but is tested
* for by Object.clone. If you implement it, you tell Object.clone that
* your data is stable enough that field-by-field copy is OK.
*/

class Enemy {

 public void munge(SideEffects md) {
   System.out.println("Object is " + md);
   md.year = 0;
   md.td.setYear(71);    // Ignore deprecation warnings
 }

} public class SideEffects implements Cloneable {

 /** When we clone a "SideEffects", this REFERENCE gets cloned */
 public Date td;  
 /** When we clone a "SideEffects", this integer does NOT get cloned */
 volatile int year;
 public static void main(String[] argv) throws CloneNotSupportedException {
   new SideEffects().process();
 }
 SideEffects() {
   td = new Date();  // today
   year = td.getYear();
 }
 public void process() throws CloneNotSupportedException {
   Enemy r = new Enemy();
   System.out.println("We have seen the enemy, and he is " + r);
   System.out.println("Today is " + td + "; nice weather, isn"t it?");
   System.out.println("And the year is " + year);
   r.munge((SideEffects)this.clone());
   System.out.println("Why, I believe it is now " + td);
   if (year == 0)    // should not happen!!
     System.out.println("** PANIC IN YEAR ZERO **");
   System.out.println("But wait, the year is still " + year);
   r.munge(this);
   System.out.println("Now I"m certain that it"s " + td);
   System.out.println("Now the year is  " + year);
 }

}




 </source>
   
  
 
  



Tests cloning to see if destination of references are also cloned

   <source lang="java">
   

// : appendixa:Snake.java // Tests cloning to see if destination // of references are also cloned. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. public class Snake implements Cloneable {

 private Snake next;
 private char c;
 // Value of i == number of segments
 public Snake(int i, char x) {
   c = x;
   if (--i > 0)
     next = new Snake(i, (char) (x + 1));
 }
 public void increment() {
   c++;
   if (next != null)
     next.increment();
 }
 public String toString() {
   String s = ":" + c;
   if (next != null)
     s += next.toString();
   return s;
 }
 public Object clone() {
   Object o = null;
   try {
     o = super.clone();
   } catch (CloneNotSupportedException e) {
     System.err.println("Snake can"t clone");
   }
   return o;
 }
 public static void main(String[] args) {
   Snake s = new Snake(5, "a");
   System.out.println("s = " + s);
   Snake s2 = (Snake) s.clone();
   System.out.println("s2 = " + s2);
   s.increment();
   System.out.println("after s.increment, s2 = " + s2);
 }

} ///:~




 </source>
   
  
 
  



The clone operation works for only a few items in the standard Java library

   <source lang="java">
   

// : appendixa:Cloning.java // The clone() operation works for only a few // items in the standard Java library. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt. import java.util.ArrayList; import java.util.Iterator; class Int {

 private int i;
 public Int(int ii) {
   i = ii;
 }
 public void increment() {
   i++;
 }
 public String toString() {
   return Integer.toString(i);
 }

} public class Cloning {

 public static void main(String[] args) {
   ArrayList v = new ArrayList();
   for (int i = 0; i < 10; i++)
     v.add(new Int(i));
   System.out.println("v: " + v);
   ArrayList v2 = (ArrayList) v.clone();
   // Increment all v2"s elements:
   for (Iterator e = v2.iterator(); e.hasNext();)
     ((Int) e.next()).increment();
   // See if it changed v"s elements:
   System.out.println("v: " + v);
 }

} ///:~




 </source>
   
  
 
  



Uses serialization to perform deep copy cloning.

   <source lang="java">
  

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class Main implements Cloneable, Serializable {

 public Object clone() {
   Object clonedObj = null;
   try {
     ByteArrayOutputStream baos = new ByteArrayOutputStream();
     ObjectOutputStream oos = new ObjectOutputStream(baos);
     oos.writeObject(this);
     oos.close();
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
     ObjectInputStream ois = new ObjectInputStream(bais);
     clonedObj = ois.readObject();
     ois.close();
   } catch (Exception cnfe) {
     System.out.println("Class not found " + cnfe);
   }
   return clonedObj;
 }

}


 </source>
   
  
 
  



Utility for object cloning

   <source lang="java">

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /**

* Utility for object cloning
* 
* @author 
*/

public class CloneUtil {

   /**
    * Provides a deep clone serializing/de-serializng objToClone     
    * 
    * @param objToClone The object to be cloned
    * @return The cloned object
    */
   public static final Object deepClone(Object objToClone)
   {
       try
       {
           ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream(100);
           ObjectOutputStream objectoutputstream = new ObjectOutputStream(bytearrayoutputstream);
           objectoutputstream.writeObject(objToClone);
           byte abyte0[] = bytearrayoutputstream.toByteArray();
           objectoutputstream.close();
           ByteArrayInputStream bytearrayinputstream = new ByteArrayInputStream(abyte0);
           ObjectInputStream objectinputstream = new ObjectInputStream(bytearrayinputstream);
           Object clone = objectinputstream.readObject();
           objectinputstream.close();
           return clone;
       }
       catch (Exception exception)
       {
           // nothing
       }
       return null;
   }

}

 </source>
   
  
 
  



You can insert Cloneability at any level of inheritance

   <source lang="java">
   

// : appendixa:HorrorFlick.java // You can insert Cloneability at any level of inheritance. // From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002 // www.BruceEckel.ru. See copyright notice in CopyRight.txt.

class Person { } class Hero extends Person { } class Scientist extends Person implements Cloneable {

 public Object clone() {
   try {
     return super.clone();
   } catch (CloneNotSupportedException e) {
     // This should never happen: It"s Cloneable already!
     throw new RuntimeException(e);
   }
 }

} class MadScientist extends Scientist { } public class HorrorFlick {

 public static void main(String[] args) {
   Person p = new Person();
   Hero h = new Hero();
   Scientist s = new Scientist();
   MadScientist m = new MadScientist();
   //! p = (Person)p.clone(); // Compile error
   //! h = (Hero)h.clone(); // Compile error
   s = (Scientist) s.clone();
   m = (MadScientist) m.clone();
 }

} ///:~




 </source>