Java and java
Assume that there is an object, and a object2 instance, which is the same as the object, is required somewhere. It is emphasized that the object and object2 are two independent instances, but at the beginning, they have the same status (the values of attribute fields are the same ). In this case, the general practice is to re-create an object object2 and assign the object field value to object2, that is, object2 = object; in this case, the two references still point to the same object, not two objects.
Clone method ()
The clone-related classes in Java are the Cloneable interface and the clone method in the Object class. The clone is achieved through collaboration between the two classes.
First, let's look at the clone () source code of the Object:
/** * Creates and returns a copy of this {@code Object}. The default * implementation returns a so-called "shallow" copy: It creates a new * instance of the same class and then copies the field values (including * object references) from this instance to the new instance. A "deep" copy, * in contrast, would also recursively clone nested objects. A subclass that * needs to implement this kind of cloning should call {@code super.clone()} * to create the new instance and then create deep copies of the nested, * mutable objects. * * @return a copy of this object. * @throws CloneNotSupportedException * if this object's class does not implement the {@code * Cloneable} interface. */ protected Object clone() throws CloneNotSupportedException { if (!(this instanceof Cloneable)) { throw new CloneNotSupportedException("Class doesn't implement Cloneable"); } return internalClone((Cloneable) this); } /* * Native helper method for cloning. */ private native Object internalClone(Cloneable o);
First, let's take a look at the description of the Cloneable interface and the clone method in the Object class in java api doc:
Java. lang. Cloneable interface (the following source cited JavaTM 2 Platform Standard Ed. 5.0 api doc)
This class implements the Cloneable interface to indicate that the Object. clone () method can legally copy such instances by field. If you call the Object clone method on an instance that does not implement the Cloneable interface, a CloneNotSupportedException exception is thrown.
By convention, classes implementing this interface should use public methods to override Object. clone (which is protected ). See Object. clone () for details about rewriting this method.
Note that this interface does not contain the clone method. Therefore, it is impossible to clone an object by implementing this interface. Even if the clone method is called by reflection, it cannot be guaranteed that it will succeed.
The Cloneable interface does not have any method. It is only a tagging interface. To have the cloning capability, the class that implements the Cloneable interface must override the clone method inherited from the Object, and call the Object clone method (see the definition of Object # clone below). The rewritten method should be public.
The clone method first determines whether the object has implemented the Cloneable interface. If there is no CloneNotSupportedException, it will call internalClone. intervalClone is a native method. Generally, the execution efficiency of the native method is higher than that of the non-native method.
When a class needs to re-write the clone method, it must inherit the Cloneable interface. Generally, the clone object is cloned through the super. clone () method.
Shadow clone)
Cloning is to copy a copy of an object. If you only need to copy the Field Values of the object (for basic data types, such as int, long, float, etc., copy the value; for the composite data type, only the field value is copied. For example, if the array variable is used, the address is copied. For the object variable, the reference of the object is copied.
For example:
Public class ShadowClone implements Cloneable {private int a; // basic type private int [] B; // non-basic type // override Object. clone () method, and change protected to public @ Override public Object clone () {ShadowClone SC = null; try {SC = (ShadowClone) super. clone ();} catch (CloneNotSupportedException e) {e. printStackTrace ();} return SC;} public int getA () {return a;} public void setA (int a) {this. a = a;} public int [] getB () {return B;} public void setB (int [] B) {this. B = B ;}}
The test code is as follows:
Public class Test {public static void main (String [] args) throws CloneNotSupportedException {ShadowClone c1 = new ShadowClone (); // assign c1.setA (100) to c1 ); c1.setB (new int [] {1000}); System. out. println ("c1: a =" + c1.getA () + "B =" + c1.getB () [0]) before cloning; // clone the object c2, modify the attributes A, B, and C of c2 ShadowClone c2 = (ShadowClone) c1.clone (); // modify c2.setA (50) of c2 ); int [] a = c2.getB (); a [0] = 5; c2.setB (a); System. out. println ("c1: a =" + c1.getA () + "B =" + c1.getB () [0]); System. out. println ("cloned c2: a =" + c2.getA () + "B [0] =" + c2.getB () [0]);}
Running result:
C1: a = 100 B = 1000 before cloning
C1: a = 100 B = 5 before cloning
Cloned c2: a = 50 B [0] = 5
Object Models of c1 and c2:
We can see that the basic type can be shallow clone. For the reference type, because the reference content is the same, changing the attributes in the c2 instance object will affect c1. Therefore, deep cloning is required for the reference type. In addition, when developing an immutable class, if the member of this immutable class has a reference type, deep cloning is required for immutable purposes.
Deep clone)
The difference between deep cloning and shallow cloning lies in the replication of composite data types. If a field in the object is of the composite type, you must create an object for the field when cloning the object.
Another example:
Public class DeepClone implements Cloneable {private int a; // basic type private int [] B; // non-basic type // override Object. clone () method, and change protected to public @ Override public Object clone () {DeepClone SC = null; try {SC = (DeepClone) super. clone (); int [] t = SC. getB (); int [] b1 = new int [t. length]; for (int I = 0; I <b1.length; I ++) {b1 [I] = t [I];} SC. setB (b1);} catch (CloneNotSupportedException e) {e. printStackTrace ();} return SC;} public int getA () {return a;} public void setA (int a) {this. a = a;} public int [] getB () {return B;} public void setB (int [] B) {this. B = B ;}}
Running result:
C1: a = 100 B = 1000 before cloning
C1: a = 100 B = 1000 before cloning
Cloned c2: a = 50 B [0] = 5
Object Model:
Deep cloning using serialization
public class DeepClone implements Serializable{ private int a; private int[] b; public int getA() { return a; } public void setA(int a) { this.a = a; } public int[] getB() { return b; } public void setB(int[] b) { this.b = b; } }
Then write the test class:
Package test2; import java. io. byteArrayInputStream; import java. io. byteArrayOutputStream; import java. io. IOException; import java. io. objectInputStream; import java. io. objectOutputStream; public class Test2 {public static void main (String [] args) throws CloneNotSupportedException {Test2 t = new Test2 (); DeepClone dc1 = new DeepClone (); // assign dc1.setA (100) to dc1; dc1.setB (new int [] {1000}); System. out. prin Tln ("dc1: a =" + dc1.getA () + "B [0] =" + dc1.getB () [0]); DeepClone dc2 = (DeepClone) t. deepClone (dc1); // modify dc2.setA (50) for c2; int [] a = dc2.getB (); a [0] = 500; System. out. println ("cloned dc1: a =" + dc1.getA () + "B [0] =" + dc1.getB () [0]); System. out. println ("cloned dc2: a =" + dc2.getA () + "B [0] =" + dc2.getB () [0]);} // use serialization and deserialization to achieve deep cloning of public Object deepClone (Object src) {Object o = null; try {if (src! = Null) {ByteArrayOutputStream baos = new ByteArrayOutputStream (); ObjectOutputStream oos = new ObjectOutputStream (baos); oos. writeObject (src); oos. close (); ByteArrayInputStream bais = new ByteArrayInputStream (baos. toByteArray (); ObjectInputStream ois = new ObjectInputStream (bais); o = ois. readObject (); ois. close () ;}} catch (IOException e) {e. printStackTrace ();} catch (ClassNotFoundException e) {e. printStackTrace () ;}return o ;}}
The running result is as follows:
Dc1 before cloning: a = 100 B [0] = 1000
After cloning, dc1: a = 100 B [0] = 1000
After cloning, dc2: a = 50 B [0] = 500
As you can see, the two referenced objects are independent of each other in the heap and do not interfere with each other. In this way, deep cloning is realized.
Summary:
1. The clone method is used to create an object copy. To use the clone method, the class must implement the java. lang. Cloneable interface to override the protected method clone. If the Clonebale interface is not implemented, CloneNotSupportedException will be thrown.
2. When cloning a java object, the constructor is not called.
3. java provides a default clone method called shallow copy to create a copy of an object and then copy the content by assigning values. This means that if your class contains a reference type, it is dangerous that both the original object and the clone object point to the same reference content, because any change to the variable field will reflect the shared content they reference. To avoid this situation, you need to perform in-depth cloning of the referenced content.
4. According to the Conventions, instance cloning should be obtained by calling super. clone (), which helps to immutable the clone object. For example, clone! = Original and clone. getClass () = original. getClass (), although these are not required
References
Http://www.cnblogs.com/shishm/archive/2011/10/10/2205743.html
Http://blog.csdn.net/bigconvience/article/details/25025561