In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this article, the editor introduces in detail "what is the role of SerialVersionUID", the content is detailed, the steps are clear, and the details are handled properly. I hope that this article "what is the role of SerialVersionUID" can help you solve your doubts? let's follow the editor's ideas to learn new knowledge.
Serializable and Externalizable
The Java class enables its serialization capabilities by implementing the java.io.Serializable interface. Classes that do not implement this interface cannot be serialized or deserialized. All subtypes of a serializable class are themselves serializable.
If you look at the source code of Serializable, you will find that it is just an empty interface with nothing in it. The Serializable interface has no methods or fields and is only used to identify serializable semantics. However, if a class does not implement this interface and wants to be serialized, a java.io.NotSerializableException exception is thrown.
How does it ensure that only methods that implement this interface can be serialized and deserialized?
The reason is that during serialization, the following code is executed:
When serializing, it determines whether the class to be serialized is of type Enum, Array, and Serializable, and throws a NotSerializableException directly if it is not.
The Externalizable interface is also provided in Java, which can also be implemented to provide serialization capabilities.
Externalizable inherits from Serializable, which defines two abstract methods: writeExternal () and readExternal ().
Developers need to override the writeExternal () and readExternal () methods when using the Externalizable interface for serialization and deserialization. Otherwise, the values of all variables will become default values.
Transient
The function of the transient keyword is to control the serialization of the variable. Adding this keyword before the variable declaration can prevent the variable from being serialized into the file. After being deserialized, the value of the transient variable is set to the initial value, such as 0 for int and null for the object.
Custom serialization policy
During serialization, if the writeObject and readObject methods are defined in the serialized class, the virtual machine attempts to call the writeObject and readObject methods in the object class for user-defined serialization and deserialization.
If there is no such method, the default calls are the defaultWriteObject method of ObjectOutputStream and the defaultReadObject method of ObjectInputStream.
User-defined writeObject and readObject methods allow users to control the serialization process, such as dynamically changing the serialization value during the serialization process.
Therefore, when you need to define a serialization policy for some special fields, you can consider using transient decoration and overriding the writeObject and readObject methods yourself, as in java.util.ArrayList.
These are the things that some readers need to know about serialization.
If we randomly find a few classes in Java that implement serialization interfaces, such as String, Integer, etc., we can find a detail, that is, these classes not only implement Serializable, but also define a serialVersionUID.
So, what exactly is serialVersionUID? Why set such a field?
What is serialVersionUID?
Serialization is the process of converting the state information of an object into a form that can be stored or transmitted. We all know that the Java object is stored in JVM's heap memory, that is, if the JVM heap no longer exists, the object disappears.
Serialization provides a solution that allows you to save objects even if JVM is down. Just like the flash drive we usually use. Serialize Java objects into a form (such as a binary stream) that can be stored or transferred, such as in a file. In this way, when the object is needed again, the binary stream is read from the file and the object is deserialized from the binary stream.
Whether the virtual machine allows deserialization depends not only on whether the classpath and functional code are consistent, but also on whether the serialization ID of the two classes is the same. This so-called serialization ID is the serialVersionUID that we define in the code.
What happens if serialVersionUID changes?
Let's give an example of what happens if serialVersionUID is modified.
Let's first execute the above code to write a User1 object to the file. Then we modify the User1 class to change the value of serialVersionUID to 2L.
Then execute the following code to deserialize the objects in the file:
The implementation results are as follows:
Java.io.InvalidClassException: com.hollis.User1; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
You can see that the above code throws a java.io.InvalidClassException and points out that the serialVersionUID is inconsistent.
This is because, when deserializing, JVM compares the serialVersionUID in the incoming byte stream with the serialVersionUID of the corresponding local entity class. If the same is considered to be consistent, it can be deserialized, otherwise there will be an exception of inconsistent serialization version, that is, InvalidCastException.
This is also the "Alibaba Java Development Manual" stipulates that in the compatibility upgrade, when modifying the class, do not modify the serialVersionUID reason. Unless the two versions are completely incompatible. So, serialVersionUID actually verifies version consistency.
If the reader is interested, you can take out all versions of the JDK code and take a look at the serialVersionUID of those backward compatible classes that have not changed. For example, the serialVersionUID of the String class is always-6849794470754667710L.
However, the author believes that this specification can actually be more stringent, that is, the regulation:
If a class implements the Serializable interface, you must manually add a private static final long serialVersionUID variable and set the initial value.
Why should a serialVersionUID be clearly identified?
Let's see what happens if we don't explicitly define a serialVersionUID in the class.
Try to modify the demo code above, first define an object with the following class, which does not define serialVersionUID, and write it to the file.
Then we modify the User1 class to add an attribute to it. Trying to read it out of the file and deserialize it.
Execution result:
Java.io.InvalidClassException: com.hollis.User1; local class incompatible: stream classdesc serialVersionUID =-298778152837257883, local class serialVersionUID = 7961728318907695402
Similarly, an InvalidClassException is thrown and points out that the two serialVersionUID are different, namely-2986778152837257883 and 7961728318907695402.
As you can see here, the system itself has added a serialVersionUID.
Therefore, once the class implements Serializable, it is recommended that you explicitly define a serialVersionUID. Otherwise, an exception will occur when you modify the class.
SerialVersionUID can be generated in two ways:
One is the default 1L, such as:
Private static final long serialVersionUID = 1L
The other is to generate a 64-bit hash field based on class name, interface name, member methods and properties, such as:
Private static final long serialVersionUID = xxxxL
The latter can be generated with the help of IDE, which will be described later.
The principle behind
To know why, let's take a look at the source code and analyze why serialVersionUID throws an exception when it changes. Where does the default serialVersionUID come from without a clear definition?
To simplify the amount of code, the call chain for deserialization is as follows:
In initNonProxy, the key code is as follows:
During deserialization, the serialVersionUID is compared, and if it is found that it is not equal, an exception is thrown directly.
Take a closer look at the getSerialVersionUID method:
When no serialVersionUID is defined, the computeDefaultSUID method is called to generate a default serialVersionUID.
This leads to the root cause of the above two problems, which is actually a strict check in the code and an serialVersionUID is automatically generated when it is not defined.
IDEA hint
To ensure that we do not forget to define serialVersionUID, we can adjust the configuration of Intellij IDEA. After implementing the Serializable interface, if serialVersionUID is not defined, IDEA (like eclipse) will prompt:
And you can generate one with one click:
Of course, this configuration does not take effect by default. You need to manually set it in IDEA:
At the place labeled 3 in the figure (Serializable class without serialVersionUID configuration), check and save.
After reading this, the article "what is the use of SerialVersionUID" has been introduced. If you want to master the knowledge points of this article, you still need to practice and use it yourself to understand it. If you want to know more about related articles, 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.