Original address: http://leihuang.org/2014/11/14/java-clone/
In Java, it is essentially means the ability to create a object with similar state as the original object.
What is clone
The meaning of the dictionary is copy (emphasis is identical to the original).
* byDefault, Java cloning are ' field by field copy ' *. Because the object class does not know the structure of the detailed class, it is not possible to determine which clone method will be called.
So the JVM prescribes clone, doing such things as the following.
- Suppose this class has only the original data type members. Then you need to create an identical object and return a reference to the new object.
- Assuming that the class includes any class-type members, only the object references of those members are copied. and references to the original object and the members of the cloned object will point to the same object.
The translation is not good. %>_<%
- If the class has only primitive data type, then a completely new copy of the object would be created and the Referen Ce to the new object copy would be returned.
- If The class contains members of any class type then only the object references to those members is copied and hence the Member references in both the original object as well as the cloned object refer to the same object.
In addition to the above two default actions. You can also overload the Clone method and make a set of your own clone methods.
Clone rule in Java
Each clone-enabled language has its own rules, and Java is no exception. Java assumes that a class needs to support clone. You will need to do things like the following:
- You must inherit the Cloneable interface---cloneable interface is broken in Java. otherwise throws java.lang.CloneNotSupportedException.
- The Clone () method in the object class must be overridden
/*creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object. The general intent are that, for any object x, the Expression:1) x.clone ()! = x would be true2) X.clone (). GetClass () = = X.ge Tclass () would be true, but these was not absolute requirements.3) X.clone (). Equals (x) would be true, this is not an Absolut e requirement.*/protected native Object [more ...] Clone () throws Clonenotsupportedexception;
- The first article indicates that the clone object is assigned a separate memory address.
- The second article indicates that the original and cloned objects should have the same type, but this is not required
- The third article shows that. The original and cloned objects call the Equals method, and should be equal. But that's not necessary.
Here we analyze by example:
Class Father implements cloneable{private int age; private String name; Private son son; Public Father (Int. age,string Name,son Son) {this.age = age; THIS.name = name; This.son = Son; } public Son Getson () {return this.son; } @Override protected Object clone () throws clonenotsupportedexception{return Super.clone (); }}class son{private int age; private String name; Public Son (Int., String name) {this.age = age; THIS.name = name; } public void SetName (String name) {this.name = name; } public String GetName () {return this.name; }}public class Clonedemo {public static void main (String args[]) throws clonenotsupportedexception{Son s = new Son ("Jack"); Father FA = new Father (max, "Tom", s); Father Clonedfa = (Father) fa.clone (); System.out.println (FA!=CLONEDFA); System.out.println (Clonedfa.getclass () ==fa.getclass ()); System.out.println (Clonedfa.equals (FA)); Now we change the FA's son name by the Clonedfa ' s son name Clonedfa.getson (). SetName ("Jay"); System.out.println (Fa.getson (). GetName ()); }}/*print:truetruefalsejay*/
Can be seen in the code above. The original and cloned Father class objects. Has two references to the same object. So you can change the son object in FA by changing the son in the Clonedfa. This is when the so-called shallow copy . Let's discuss the shallow copy and deep copy in detail below.
Shallow copy (shallow cloning)
This is the default implementation in Java . The example above is a shallow copy. Do not create a new cloned copy object son, but direct two references to the same object.
Deep copy
If we want a clone which is independent of original and making changes in clone should not affect Original.you can try Dee P cloning.
We change the Clone () method in the Father class.
@Overrideprotected Object Clone () throws Clonenotsupportedexception { Father fa = (Father) super.clone (); Fa.setson (Son) Fa.getson (). Clone ()); return FA;}
And we need Override the Clone () method in the Son class. Like this.
@Overrideprotected Object Clone () throws Clonenotsupportedexception { return Super.clone ();}
Now we have a deep copy.
Copy constructor
A special constructor for copying constructors. It speaks its own class type as a parameter. We pass an instance of a class to the copy constructor. It then returns a new instance of the class. Lets see this in example
public class Pointone { private Integer x; Private Integer y; Public Pointone (Pointone point) { this.x = point.x; This.y = Point.y; }}
Assuming that you want to inherit it, you need to copy the number of references to the subclass and pass the reference to the constructor of the parent class.
For example, the following:
public class Pointtwo extends pointone{ private Integer z; Public Pointtwo (Pointtwo point) { Super ';//call Super class constructor here this.z = point.z; }}
Here is the test code:
Class test{public static void Main (string[] args) { Pointone one = new Pointone; Pointtwo-N = new Pointtwo Pointone clone1 = new Pointone (one); Pointone clone2 = new Pointone (both); Let check for class types System.out.println (Clone1.getclass ()); System.out.println (Clone2.getclass ());} } Output:class Corejava.cloning.PointOneclass Corejava.cloning.PointOne
You can also use the static factory method to implement it.
public class Pointone { private Integer x; Private Integer y; Public Pointone (integer x, integer y) { this.x = x; This.y = y; } Public Pointone CopyPoint (Pointone point) throws Clonenotsupportedexception { if (!) ( Point instanceof cloneable) { throw new clonenotsupportedexception ("Invalid cloning"); } Can do multiple other things here return new Pointone (Point.x, Point.y);} }
Cloning with serialization
This is an exception to a deep copy method. Here is not much to say, see specifically: A Mini Guide for implementing serializable interface in Java
Best practices
1) When you don ' t know whether-can call the Clone () method of a particular class as you're not sure if it's implemen Ted in so class, you can check with checking if the class is instance of "Cloneable" interface as below.
if (obj1 instanceof cloneable) { obj2 = Obj1.clone ();} Dont do this. Cloneabe dont has any methodsobj2 = (cloneable) obj1.clone ();
2) No constructor is called on the object being cloned. As a result, it is your responsibility, and the sure all of the members has been properly set. Also, if you is keeping track of number of objects in system by counting the invocation of constructors, you got a new ad Ditional Place to increment the counter.
Reference:
- A Guide to object cloning in Java
- Effective--java Item 11:override Clone judiciously (more specifically, the pros and cons of various clone methods are spoken)
2014-11-14 15:48:12
Brave,happy,thanksgiving!
Copyright notice: This article Bo Master original article. Blog, not reproduced without consent.
J Detailed description of Ava in the clone approach