In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-09 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
In this issue, the editor will bring you about how to deeply understand the original serialization mechanism of Java. The article is rich in content and analyzes and narrates it from a professional point of view. I hope you can get something after reading this article.
Concept
If an object wants to be stored on a hard disk, it must rely on a certain data format. This process of converting objects to hard disk storage format is called object serialization. Similarly, the operation of converting these files back into objects in the program is called deserialization. Some complex solutions may be the way to convert objects to json strings, which has the advantage of being easy to read, but still too inefficient. So the solution of Java serialization is to convert the object into a binary stream to achieve data persistence. This article will explain the implementation and principle of serialization in detail.
Realize
Prepare for
We have a normal object here, and note that this class and all objects used in it need to implement the serialization interface Serializable:
Class Demo implements Serializable {int val= 10 hashCode string time= new SimpleDateFormat ("HH:mm:ss") .format (new Date ()); AA = new A (20); @ Overridepublic String toString () {return "[hashcode=" + hashCode () + "val=" + val + ", time=" + time + ", A.vale =" + a.val + "]";}}
This An is a normal object, as follows:
Class An implements Serializable {int val = 20th public A (int val) {this.val = val;}}
Now we have a Demo object to output the flag string of this object:
Demo demo = new Demo (); System.out.println (demo.toString ())
Output result:
[hashcode=1625635731 val=10, time=20:28:56, A.val=20]
Serialization
Now that we need to serialize this object to a binary stream, we need the following:
FileOutputStream fileOutputStream = new FileOutputStream ("target"); ObjectOutputStream objectOutputStream = new ObjectOutputStream (fileOutputStream); objectOutputStream.writeObject (demo); objectOutputStream.flush (); objectOutputStream.close ()
In this way, the demo object is persisted to the target file on the hard disk.
Deserialization
Conversely, if we want to take this object out of the target file, we need to do the following:
FileInputStream fileInputStream = new FileInputStream ("target"); ObjectInputStream objectInputStream = new ObjectInputStream (fileInputStream); Demo newDemo = (Demo) objectInputStream.readObject ()
Inspection
Now, let's verify whether the two objects are the same object with the following statement:
System.out.println (newDemo.toString ()); System.out.println ("demo = = newDemo:" + (demo = = newDemo))
Output
[hashcode=885284298 val=10, time=20:28:56, A.val=20] demo = = newDemo: false
We will find that although the value of the deserialized object is the same as the original object, it is not the same object, which is very important.
Principle
We open the serialized target file, which needs to be opened as a binary stream:
The file can be divided into five parts:
Header: the declaration file is an object serialization file, and the serialized version class description is declared: declare the class information, including the class name, serialization id, and the number of fields and other attributes that describe the parent class information that describes the actual value of the object property.
In other words, in this binary file, all the information of a class can be indicated through these parts. During deserialization, Java will recover the data from the file according to the specified file format.
Matters needing attention
Serialized classes must implement the Serializable interface all custom objects contained in serialized classes need to implement the Serializable interface
Why are these two points? let's take a look at the writeObject0 method in ObjectOutputStream, which intercepts a short segment:
If (obj instanceof String) {writeString ((String) obj, unshared);} else if (cl.isArray ()) {writeArray (obj, desc, unshared);} else if (obj instanceof Enum) {writeEnum ((Enum) obj, desc, unshared);} else if (obj instanceof Serializable) {writeOrdinaryObject (obj, desc, unshared);} else {if (extendedDebugInfo) {throw new NotSerializableException (cl.getName () + "\ n" + debugInfoStack.toString ());} else {throw new NotSerializableException (cl.getName ());}}
The obj in this code is not only the serialized object, but also all the fields in the object, that is, the domain object must be one of the string, array, enumeration and serialization interfaces, otherwise an exception will be thrown
Serialize ID
In fact, there is one more note that I have stayed here to say:
The field name, type, and number of objects cannot be changed between serialization and deserialization
Why, let's take a look at a piece of code in deserialization:
If (model.serializable = = osc.serializable & &! cl.isArray () & & suid! = osc.getSerialVersionUID ()) {throw new InvalidClassException (osc.name, "local class incompatible:" + "stream classdesc serialVersionUID =" + suid + ", local class serialVersionUID =" + osc.getSerialVersionUID ());}
This is a section of the initNonProxy method in ObjectStreamClass, which is the core method for reading our serialized file to initialize the class descriptor.
But we don't focus here, we focus on a comparison between suid and osc.getSerialVersionUID (), which involves the concept of serializing id, and the declaration of serializing id looks like this:
Class Demo implements Serializable {/ / this serialized id general ide will provide automatically generated plug-ins. If you are interested, you can download private static final long serialVersionUID =-5809782578272943999L
The key to the success of Java deserialization is to compare whether the serialization id of the file and the serialization id of the class are consistent. If so, the object in the file and the class object are considered to be the same object, otherwise, it means that the two classes are not the same class at all, and exceptions are likely to occur if the conversion is forced.
But we can also deserialize successfully without manually setting the serialization id before, right? In fact, we were able to deserialize successfully only because we did not change the original class. If we do not set the serialization id, any of the following actions will cause deserialization failure:
Modified field / method name / type to add or remove field / method
See, even if we just change the name of the field, it will lead to the failure of deserialization. If we don't pay attention to this, it will lead to the collapse of all deserialization operations, but as long as we set a serialization id, even if we delete all the elements in the class, we will still deserialize successfully, just losing the attribute.
The above is the editor for you to share how to deeply understand the Java native serialization mechanism, if you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.