This article is a detailed analysis and introduction to the method of serialized access to achieve deep cloning of Java objects. Friends in need can refer to it
We know that in Java, a non-prototype type type After the object reference is assigned to the reference of another object, the two references point to the same object, such as:
The code is as follows:
public class DeepCloneTest { private class CloneTest { private Long myLong = new Long(1); } public static void main(String args[]) { new DeepCloneTest().Test(); } public void Test() { CloneTest ct1 = new CloneTest(); CloneTest ct2 = ct1; // to see if ct1 and ct2 are one same reference. System.out.println("ct1: " + ct1); System.out.println("ct2: " + ct2); // if ct1 and ct2 point to one same object, then ct1.myLong == ct2.myLong. System.out.println("ct1.myLong: " + ct1.myLong); System.out.println("ct2.myLong: " + ct2.myLong); // we change ct2's myLong ct2.myLong = 2L; // to see whether ct1's myLong was changed. System.out.println("ct1.myLong: " + ct1.myLong); System.out.println("ct2.myLong: " + ct2.myLong); }}
out put:
ct1: DeepCloneTest$CloneTest@c17164
ct2: DeepCloneTest$CloneTest@c17164
ct1.myLong: 1
ct2.myLong: 1
ct1.myLong: 2
ct2.myLong: 2
This is very easy, everyone who studies Java probably knows it (are those who don’t know, those who study Java?).
In memory, the object reference is stored in the stack, the object data is stored in the heap, and the reference in the stack points to the object in the heap. Here are the references in the two stacks, pointing to the same object in the heap. Therefore, when the myLong of ct2 is changed, you can see that the myLong value of ct1 also changes accordingly. If represented by a diagram, it is easy to understand. :
The left side is the stack area. There are two references in this area with the same value. They point to the same object in the right heap area. .
Most of the time, we will use this feature of the Java language to do what we want to do. For example, pass the object reference as an input parameter into a method, and in the method, make corresponding modifications to the object pointed to by the reference. But sometimes, we want to construct an object that has exactly the same content as an existing object but references a different object. To do this,you can do this:
The code is as follows:
public class DeepCloneTest{ // must implements Cloneable. private class CloneTest implements Cloneable{ private Object o = new Object(); public CloneTest clone() { CloneTest ct = null; try { ct = (CloneTest)super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return ct; } } public static void main(String args[]) { new DeepCloneTest().Test(); } public void Test() { CloneTest ct1 = new CloneTest(); CloneTest ct2 = ct1.clone(); // to see if ct1 and ct2 are one same reference. System.out.println("ct1: " + ct1); System.out.println("ct2: " + ct2); // whether ct1.o == ct2.o ? yes System.out.println("ct1.o " + ct1.o); System.out.println("ct1.o " + ct1.o); }}
out put:
ct1: DeepCloneTest$CloneTest@c17164
ct2: DeepCloneTest$CloneTest@1fb8ee3
ct1.o java.lang.Object@61de33
ct1.o java .lang.Object@61de33
It can be seen from the output that ct1 and ct2 are indeed two different references, so we take it for granted that ct1.o and ct2.o are also two different objects, but from the output It can be seen that this is not the case! ct1.o and ct2.o are the same object! The reason is that although cloning is used, the above is only a shallow clone, represented graphically:
Do you see the o above? In fact, it is shared by two objects. This is equivalent to, you originally had a sheepfold 1 with a sheep in it, and then you made a sheepfold 2. Without taking the sheep out of sheepfold 1, you also penned the sheep in it. In pen 2, you thought you had two sheep, but actually? everybody knows.
This is the result of shallow cloning:If you want two objects to have independent o, you must clone o again. Some people may think that this is nothing, just do it, but have you ever thought about it, if there is more than one o, and there are many, many things similar to o, do you clone them one by one? Obviously it's unrealistic.
One solution is:Serialize and store the object into the stream first, and then read the object out of the stream, so that it can be guaranteed to be read. The data and the values in the previous object are exactly the same, just like a complete copy.
The code is as follows:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class DeepCloneTest { // must implements Cloneable. private class CloneTest implements Serializable{ private static final long serialVersionUID = 1L; private Object o = new Object(); public CloneTest deepClone() { CloneTest ct = 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); ct = (CloneTest)ois.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return ct; } } public static void main(String args[]) { new DeepCloneTest().Test(); } public void Test() { CloneTest ct1 = new CloneTest(); CloneTest ct2 = ct1.deepClone(); // to see if ct1 and ct2 are one same reference. System.out.println("ct1: " + ct1); System.out.println("ct2: " + ct2); // whether ct1.o == ct2.o ? no System.out.println("ct1.o " + ct1.o); System.out.println("ct1.o " + ct1.o); } }
At this time, the data in the memory is like this:
Clone task completed.
The above is the detailed content of Detailed explanation of examples of object cloning implemented by java serialization access. For more information, please follow other related articles on the PHP Chinese website!