Objective
Java Cloning (clone) is one of the features of the Java language, but it is rarely used in practice. But sometimes cloning can be more convenient and more efficient.
For clones (clone), Java has some limitations:
1. The cloned class must implement the Cloneable interface itself to indicate that Object.clone()
the method can legitimately replicate the class instance by field. The Cloneable interface is actually an identity interface and does not have any interface methods.
2. A class that implements the Cloneable interface should use a public method override Object.clone
(it is protected). It is impossible for an object to clone it if it implements this interface. Even if the Clone method is a reflexive invocation, there is no guarantee that it will succeed.
3, in the Java.lang.Object
class cloning method is so defined:
Protected Object Clone ()
throws Clonenotsupportedexception
Creates and returns a copy of this object. Indicates a protected method that is visible in the same package.
By convention, the returned object should be obtained by calling super.clone
.
Assignments in Java
In Java, assignment is very common, and a simple assignment is as follows
Original type
int a = 1;
int b = A;
Reference type
string[] weekdays = new STRING[5];
string[] Gongzuori = weekdays;//Copy reference only
In the above code.
1, if the original data type, the assignment is passed the real value
2. If you are referencing a data type, the assignment is passed as a reference to the object, not an object.
Understanding the difference between data types and reference types makes it easy for us to understand clones.
Clone
In Java, clone is the process of copying an existing object in memory from another object that is identical to it. Clones in Java are domain-by-field replication.
To support the Clone method in Java, you need to implement the Cloneable interface first
Cloneable is actually a bit strange, it's different from the interface we use, it doesn't contain any methods, it's just a markup interface.
Its source code is as follows
Public interface Cloneable {
}
About cloneable, you need to be aware of
1, if you want to support clone, you need to implement the Cloneable interface
2. If there is no call clone method to implement the Cloneable interface, a Clonenotsupportedexception exception is thrown.
Then rewrite the Clone method and modify it to the public access level
Static Class Cloneableimp implements cloneable {public
int count;
public child child;
@Override Public
Object Clone () throws Clonenotsupportedexception {return
super.clone ();
}
}
Calling the Clone method to copy an object
Cloneableimp imp1 = new Cloneableimp ();
Imp1.child = new Child ("Andy");
try {
Object obj = Imp1.clone ();
Cloneableimp IMP2 = (cloneableimp) obj;
System.out.println ("main imp2.child.name=" + imp2.child.name);
} catch (Clonenotsupportedexception e) {
e.printstacktrace ();
}
Shallow copy
The above code implements a clone that actually belongs to a shallow copy (shallow copy).
About shallow copies, you should know.
1, using the default clone method
2. Make a value copy of the original data field
3. Copy references only for reference types
4, fast implementation, high efficiency
5, can not do 100% separation of data.
6. If an object contains only the original data field or the Mutable object field, it is recommended that you use a shallow copy.
With regard to the inability to do data separation, we can use this code to verify
Cloneableimp imp1 = new Cloneableimp ();
Imp1.child = new Child ("Andy");
try {
Object obj = Imp1.clone ();
Cloneableimp IMP2 = (cloneableimp) obj;
Imp2.child.name = "Bob";
System.out.println ("main imp1.child.name=" + imp1.child.name);
} catch (Clonenotsupportedexception e) {
e.printstacktrace ();
}
The above code we use the Imp1 clone method to clone the IMP2, then modify it imp2.child.name
to Bob, and then print imp1.child.name
the result is
The reason is that a shallow copy does not do 100% separation of data, IMP1 and IMP2 share the same child object, so one modification affects the other.
Deep copy
Deep copy can solve the problem of data 100% separation. You just need to make some changes to the code above.
1, child implementation cloneable interface.
public class child implements cloneable{public
String name;
Public Child (String name) {
this.name = name;
}
@Override public
String toString () {return
' child [name= ' + name + '] ';
}
@Override
protected Object Clone () throws Clonenotsupportedexception {return
super.clone ();
}
}
2. Rewrite the Clone method to invoke the Clone method of the data field.
Static Class Cloneableimp implements cloneable {public
int count;
public child child;
@Override Public
Object Clone () throws Clonenotsupportedexception {
Cloneableimp obj = (cloneableimp) Super.clone ();
Obj.child = (Child) Child.clone ();
return obj;
}
}
When we modify imp2.child.name
it again it will not affect imp1.child.name
the value because IMP1 and imp2 each have their own child objects because of the 100% isolation of the data.
Some features of deep copy
1, you need to rewrite the Clone method, not only the method of the parent class, but also call the attribute's Clone method
2, do the original object and clone object between 100% data separation
3, if the object has a reference type of properties, it is recommended to use a deep copy
4, deep copy is more time-consuming and less efficient than shallow copy
Why use clones
The important and common common is that an API needs to provide a list collection, but does not want the caller's modifications to affect its own changes, so it is necessary to clone an object to achieve the purpose of data isolation.
Should try to avoid clone
1. Typically, an interface is implemented to show what the class can do for its customers, and cloneable is just a markup interface, and it also changes the behavior of the method of hand protection in the superclass, an extremely atypical use of the interface and is not worth emulating.
The Javadoc description of the 2.Clone method convention and its fragile clone method is somewhat ambiguous, as follows for the Java SE8 Convention
The Clone method creates and returns a copy of the object. The exact meaning of the copy depends on the class of the object. The general implication is that for any object x, an expression
x.clone() != x 为 true x.clone().getClass() == x.getClass()
also returns true, but does not have to x.clone().equals(x)
return true, but is not required
The second and third expressions above can easily return false. So the only thing that can guarantee permanent true is the expression one, that is, two objects are independent objects.
3. The final domain of the Mutable object in the Clone method, if we need to copy the final domain of the Mutable object, it cannot actually be compiled because of the final limit. Therefore, in order to implement cloning, we need to consider the final keyword of the mutable object domain.
4. Thread safety If you decide to implement the Cloneable interface with a thread-safe class, you need to ensure that its Clone method is synchronized. The default Object.clone
method is not to do synchronization.
In general, the Clone method in Java is not actually perfect, and it is recommended that you avoid it as much as possible. The following are some alternative scenarios.
Copy Constructors
You can also implement copies of objects by using the Copy Builder.
1, the copy constructor is also a constructor
2, accept only one parameter, the parameter type is the current class
3, the purpose is to generate a new object with the same parameters
4, copy the constructor compared to the advantages of the Clone method is simple, easy to implement.
A code example that uses the Copy Builder
public class Car {
Wheel Wheel;
String manufacturer;
Public car (Wheel Wheel, String manufacturer) {
this.wheel = Wheel;
This.manufacturer = manufacturer;
}
Copy constructor public car (car car
) {This
(Car.wheel, car.manufacturer);
}
public static class Wheel {
String brand;
}
}
Note that the above code is implemented as a shallow copy, and if you want to implement a deep copy, refer to the following code
Copy constructor public car (car car
) {
Wheel Wheel = new Wheel ();
Wheel.brand = Car.wheel.brand;
This.wheel = wheel;
This.manufacturer = Car.manufacturer;
}
In order to be more convenient, we can also add a static method for the above class
public static car newinstance [car] {return
new car (car);
}
Using serializable to implement deep copy
In fact, using serialization can also implement deep copies of objects. The abbreviated code is as follows
public class Deepcopyexample implements serializable{
private static final long Serialversionuid = 6098694917984051357L;
public child child;
Public deepcopyexample Copy () {
deepcopyexample copy = null;
try {
Bytearrayoutputstream BAOs = new Bytearrayoutputstream ();
ObjectOutputStream oos = new ObjectOutputStream (BAOs);
Oos.writeobject (this);
Bytearrayinputstream Bais = new Bytearrayinputstream (Baos.tobytearray ());
ObjectInputStream ois = new ObjectInputStream (Bais);
copy = (deepcopyexample) ois.readobject ();
} catch (IOException e) {
e.printstacktrace ();
} catch (ClassNotFoundException e) {
e.printstacktrace ();
}
return copy;
}
Where the child must implement the Serializable interface
public class child implements serializable{
private static final long serialversionuid = 6832122780722711261L;
Public String name = "";
Public Child (String name) {
this.name = name;
}
@Override public
String toString () {return
' child [name= ' + name + '] ';
}
}
Working with examples and testing code
deepcopyexample example = new Deepcopyexample ();
Example.child = new Child ("example");
Deepcopyexample copy = Example.copy ();
if (copy!= null) {
copy.child.name = "Copied";
System.out.println ("example.child=" + Example.child + "; copy.child=" + Copy.child);
}
Output results: example.child=child [Name=example];copy.child=child [name=copied]
From the output, the change of the child value of the Copy object does not affect the child value of the example object, that is, a deep copy of the object can be implemented using serialization.
Summarize
The above is the entire content of the cloning in Java, I hope this article for you to learn Java can help.