Sometimes we see the following methods in many cases involving serialization and deserialization through Java object streams:
private void WriteObject (Java.io.ObjectOutputStream s) throws Java.io.IOException
private void ReadObject (Java.io.ObjectInputStream s) throws Java.io.IOException, ClassNotFoundException
And when we write our single example class, if we are not using the implementation form of enumerations, we will often see the following method in order to ensure that the deserialized object does not break the single case.
Private Object Readresolve ()
Are you curious as to why these methods are private, and you will find that they are not used in their own classes ... So what is the use of these methods? Let's follow the source code to see.
Because the ReadObject method is the same as the WriteObject method, I'll just explain the approximate process of the ReadObject method, and a few key points related to it.
First, let's look at a very simple program code:
public static void Main (string[] args) throws Exception {
set<string> Set = new hashset<string> ();
Set.add ("11111");
Set.add ("22222");
SYSTEM.OUT.PRINTLN (set);
Try (objectoutputstream oos = new ObjectOutputStream (New FileOutputStream ("C:\\users\\lianghaohui\\desktop\\set.obj") )) {
oos.writeobject (set);
}
Set.clear ();
SYSTEM.OUT.PRINTLN (set);
Try (objectinputstream ois = new ObjectInputStream (New FileInputStream ("C:\\users\\lianghaohui\\desktop\\set.obj")) {
set = (set<string>) ois.readobject ();
}
SYSTEM.OUT.PRINTLN (set);
}
The result is no suspense, and will print out the following:
[11111, 22222]
[]
[11111, 22222]
However, if we read the source code of HashSet, you will find
Yes, the entire map (HashSet and Linkedhashset) for saving information is implemented with HashMap, copyonwritearrayset the bottom is implemented with Copyonwritearraylist, And so on a variety of set implementation class source code is interested to read the source code is used transient keyword modified.
However, it is clear that our information has been serialized successfully, otherwise the information stored in the set is lost when deserialized. The secret of true realization lies in the ReadObject method and WriteObject method mentioned above. Here simply introduces the ReadObject method, the WriteObject method is similar, does not introduce.
Due to space constraints, here does not post the source code of ReadObject and one by one analysis, it mainly do things, is actually read the normal should be serialized field information, then construct a map, and then through the object stream, the original through the object stream into the file inside the map information (capacity, Each item information, and so on, and then reconstruct a map, so that the information we keep in the set is not lost after the serialization and deserialization of the object stream has passed. So, this is the private ReadObject method is how to be invoked.
Simple call Flowchart (specific information, or you need to track the source code):
See here, we have probably understood, why such as HashSet class inside, want to write private ReadObject method, because the object stream reading process, it will through the form of reflection, it calls the private ReadObject method. Of course, the whole process came here, or did not walk, there are a lot of steps to do, but because it does not belong to the scope of the discussion, here is not described.
However, we still have a doubt, that is when the ObjectStreamClass was produced. and Readobjectmethod This attribute is how to get it.
The answer is in the Readordinaryobject method invocation of the ObjectInputStream class:
Finally, we also know in the source code inside, is where obtains, we single example, wrote that private Readresolve method reference. So which step in the whole process, through that reference, actually called our Readresolve method. The answer is the Readordinaryobject method of the ObjectInputStream class at the very beginning, and after the Readserialdata () method is called, the object of the ObjectStreamClass class is called. The Invokereadresolve (Object obj) method, which invokes the Readresolve method we write by reflection, is no longer discussed here.
This article is also to end, the first source analysis of the article, has tried to maintain space in the case, as far as possible to explain what I want to elaborate on the content, also said that the magic of the three private method: Readobject,writeobject, Where the readresolve was invoked.
Finally, there are some deficiencies, I hope to point out, thank you.