Java clone () method instructions, javaclone
One advantage of Java is that it removes the pointer concept, but many programmers often ignore the difference between objects and references in programming, in addition, Java cannot solve the problem of object Replication through simple assignment. during development, the clone () method is often used to copy objects.
For example, when the function parameter type is a custom class, it is a reference transfer instead of a value transfer. The following is an example:
Java code
- Public class {
- Public String name;
- }
Java code
- Public class testClone {
- Public void changeA (A ){
- A. name = "B ";
- }
- Public void changInt (int I ){
- I = I * 2 + 100;
- }
- /**
- * @ Param args
- */
- Public static void main (String [] args ){
- // TODO Auto-generated method stub
- TestClone test = new testClone ();
- A a = new ();
- A. name = "";
- System. out. println ("before change: a. name =" + a. name );
- Test. changeA ();
- System. out. println ("after change: a. name =" + a. name );
- Int I = 1;
- System. out. println ("before change: I =" + I );
- Test. changInt (I );
- System. out. println ("after change: I =" + I );
- }
- }
The output result is as follows:
Java code
- Before change: a. name =
- After change: a. name = B
- Before change: I = 1
- After change: I = 1
From this example, we know that Java processes objects differently from basic data types. In Java, when an object is passed as an entry parameter, the default value is "reference transfer", that is, only one "Reference" of the object is passed ", the concept of "Reference" is the same as that of pointer reference in C language. When the function body changes the input variable, it is essentially a direct operation on this object.
Except for "reference transfer" when the function transfers values, it is "reference transfer" when "=" is used to assign values to object variables, for example:
Java code
- A a1 = new ();
- A a2 = new ();
- A1.name = "a1 ";
- A2 = a1;
- A2.name = "a2 ";
- System. out. println ("a1.name =" + a1.name );
- System. out. println ("a2.name =" + a2.name );
The output result is as follows:
Java code
- A1.name = a2
- A2.name = a2
If we want to use a2 to save the data of the a1 object, but do not want the data of the a2 object to be changed, it will not affect A1. The clone () method is the simplest and most efficient method.
Next we will implement the clone method of.
Java code
- Public class A implements Cloneable {
- Public String name;
- Public Object clone (){
- A o = null;
- Try {
- O = (A) super. clone ();
- } Catch (CloneNotSupportedException e ){
- E. printStackTrace ();
- }
- Return o;
- }
- }
First, we need to implement the Cloneable interface, then reload the clone method, and finally call super in the clone () method. clone (), which also means no matter what the clone class's inheritance structure is, super. clone () directly or indirectly calls java. lang. object Class clone () method.
Java code
- A a1 = new ();
- A a2 = new ();
- A1.name = "a1 ";
- A2 = a1;
- A2.name = "a2 ";
- System. out. println ("a1.name =" + a1.name );
- System. out. println ("a2.name =" + a2.name );
The output result is as follows:
Java code
- A1.name = a1
- A2.name = a2
When the Class A member variable type is the basic java type (plus the String type), you only need to implement the above simple clone (called Shadow clone. However, if the Class A member variable is of an array or complex type, deep clone is required.
Java code
- Public class A implements Cloneable {
- Public String name [];
- Public (){
- Name = new String [2];
- }
- Public Object clone (){
- A o = null;
- Try {
- O = (A) super. clone ();
- } Catch (CloneNotSupportedException e ){
- E. printStackTrace ();
- }
- Return o;
- }
- }
Test code
Java code
- A a1 = new ();
- A a2 = new ();
- A1.name [0] = "";
- A1.name [1] = "1 ";
- A2 = (A) a1.clone ();
- A2.name [0] = "B ";
- A2.name [1] = "1 ";
- System. out. println ("a1.name =" + a1.name );
- System. out. println ("a1.name =" + a1.name [0] + a1.name [1]);
- System. out. println ("a2.name =" + a2.name );
- System. out. println ("a2.name =" + a2.name [0] + a2.name [1]);
Output result:
Java code
- A1.name = [Ljava. lang. String; @ 757aef
- A1.name = b1
- A2.name = [Ljava. lang. String; @ 757aef
- A2.name = b1
As you can see, the hash values of a1.name and a2.name are all @ 757aef. That is to say, the Shadow clone to name array is just clone their address! The solution is to perform in-depth clone.
Java code
- Public Object clone (){
- A o = null;
- Try {
- O = (A) super. clone ();
- O. name = (String []) name. clone (); // it's actually quite simple. ^_^
- } Catch (CloneNotSupportedException e ){
- E. printStackTrace ();
- }
- Return o;
- }
The output result is:
Java code
- A1.name = [Ljava. lang. String; @ 757aef
- A1.name = a1
- A2.name = [Ljava. lang. String; @ d9f9c3
- A2.name = b1
Note that when Class A has more complex member variables, such as A Vector container that stores object addresses, the clone must be complete.
Java code
- Public class A implements Cloneable {
- Public String name [];
- Public Vector <B> claB;
- Public (){
- Name = new String [2];
- ClaB = new Vector <B> ();
- }
- Public Object clone (){
- A o = null;
- Try {
- O = (A) super. clone ();
- O. name = (String []) name. clone (); // deep clone
- O. claB = new Vector <B> (); // run the clone command to the end.
- For (int I = 0; I <claB. size (); I ++ ){
- B temp = (B) claB. get (I). clone (); // Of course, Class B also needs to implement the corresponding clone method
- O. claB. add (temp );
- }
- } Catch (CloneNotSupportedException e ){
- E. printStackTrace ();
- }
- Return o;
- }
- }