In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article introduces the relevant knowledge of "how to understand serialization". In the operation of actual cases, many people will encounter such a dilemma. Then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
The main content of this article
Background
In Java language, many objects are produced when the program is running, and the object information keeps its state in memory only when the program is running. Once the program stops and the memory is released, the object no longer exists.
How can an object be saved permanently?-object serialization.
What is serialization and deserialization?
Serialization: object to IO data flow
Deserialization: IO data streams to objects
What are the usage scenarios?
The Java platform allows us to create reusable Java objects in memory, but in general, these objects can only exist when JVM is running, that is, the life cycle of these objects is no longer than that of JVM. However, in real applications, it may require that the specified object be saved (persisted) after the JVM stops running, and the saved object can be read again in the future. Java object serialization can help us achieve this functionality.
With Java object serialization, when an object is saved, its state is saved as a set of bytes, which are then assembled into objects in the future. It must be noted that object serialization holds the "state" of the object, that is, its member variables. From this, object serialization does not care about static variables in the class.
In addition to object serialization when persisting objects, object serialization is used when using RMI (remote method invocation) or when passing objects over the network.
Java serialization API provides a standard mechanism for handling object serialization, and the API is easy to use.
It is useful in many frameworks, such as the use of serialization in a typical dubbo framework.
What is the purpose of serialization?
The serialization mechanism allows the serialization of Java objects to be converted into byte sequences, which can be saved on disk or transmitted over the network to later restore to the original object. The serialization mechanism enables objects to exist independently from the running of the program.
Serialization implementation
In the Java language, there are two common ways to implement serialization:
Implement the Serializable interface
Implement the Externalizable interface
Next, let's talk about these two implementation methods in detail.
Implement the Serializable interface
Create a User class to implement the Serializable interface and serialize, roughly as follows:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
The object entity class implements the Serializable tag interface.
Create a serialized output stream object ObjectOutputStream. The creation of this object depends on other output stream objects. Usually we serialize the object into a file store, so here we use the file-related output stream object FileOutputStream.
The object is serialized into a file through the writeObject () method of ObjectOutputStream.
Close the stream.
Here is the code:
Package com.tian.my_code.test.clone; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; public class User implements Serializable {private int age; private String name; public User () {} public User (int age, String name) {this.age = age This.name = name;} / / set get omit public static void main (String [] args) {try {ObjectOutputStream objectOutputStream = new ObjectOutputStream (new FileOutputStream ("user.txt")); User user=new User (22, "Lao Tian"); objectOutputStream.writeObject (user) } catch (IOException e) {e.printStackTrace ();}
Create a User object, and then save the User object in user.txt.
Deserialization
There are roughly three steps:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
Create the input stream object ObjectOutputStream. Also dependent on other input stream objects, here is the file input stream FileInputStream.
The objects in the file are read into memory through the readObject () method of ObjectInputStream.
Close the stream.
Let's deserialize the code:
Package com.tian.my_code.test.clone; import java.io.*; public class SeriTest {public static void main (String [] args) {try {ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("user.txt")); User user= (User) ois.readObject (); System.out.println (user.getName ()) } catch (Exception e) {e.printStackTrace ();}
Run this code and output the result:
Open the user.tst file using IDEA:
Use the editor 16 mechanism to view
We don't need to care too much about the contents of the document and continue to talk about our key points.
Serialization stores the User object in a file, and then deserialization reads the contents of the file and creates the object.
The A side saves the object User to the file user.txt, and the B side can read the file through the network or other means, and then deserialize it to get the User object created by A side.
Development
What if there is a change in the User attribute that the B side gets? For example, add a field
Private String address
Deserialize again and an error will be reported.
Add serialVersionUID
Package com.tian.my_code.test.clone; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; public class User implements Serializable {private static final long serialVersionUID = 2012965743695714769L; private int age; private String name Public User () {} public User (int age, String name) {this.age = age; this.name = name } / / set get omits public static void main (String [] args) {try {ObjectOutputStream objectOutputStream = new ObjectOutputStream (new FileOutputStream ("user.txt")); User user=new User (22, "Lao Tian"); objectOutputStream.writeObject (user) } catch (IOException e) {e.printStackTrace ();}
Deserialization is performed again, and the result is normal
Then we add the field and the corresponding get/set method again
Private String address
Perform deserialization again
Deserialization succeeded.
If the serializable class does not explicitly declare serialVersionUID, the serialization runtime calculates the default serialVersionUID value of the class based on all aspects of the class, as described in the Java (TM) object serialization specification.
However, it is strongly recommended that all serializable classes declare serialVersionUID values explicitly because calculating the default serialVersionUID is highly sensitive to class details and can vary depending on the compiler implementation, which can lead to unexpected InvalidClassException during deserialization.
Therefore, in order to ensure the consistency of serialVersionUID values across different Java compiler implementations, serialized classes must declare an explicit serialVersionUID value.
It is strongly recommended that you use the private modifier to display the declaration serialVersionUID, if possible, because such a declaration applies only to the direct declaration class-- the serialVersionUID field is not useful as an inherited member. Array classes cannot declare an explicit serialVersionUID, so they always have default calculated values, but array classes do not have the requirement to match serialVersionUID values.
So, try to show the declaration, so that the serialized class can be deserialized successfully even if there are field modifications, because of the existence of serialVersionUID. Better compatibility is guaranteed.
How to quickly add serialVersionUID to IDEA?
Our class implements the Serializable interface. With the mouse over the class, the Alt+ enter key can be added.
Implement the Externalizable interface
By implementing the Externalizable interface, you must implement the writeExternal and readExternal methods.
@ Override public void writeExternal (ObjectOutput out) throws IOException {} @ Override public void readExternal (ObjectInput in) throws IOException, ClassNotFoundException {}
Externalizable is a subinterface of Serializable.
Public interface Externalizable extends java.io.Serializable {
Continue to use the previous User, code for modification:
Package com.tian.my_code.test.clone; import java.io.*; public class User implements Externalizable {private int age; private String name; public User () {} public User (int age, String name) {this.age = age; this.name = name } / / set get public static void main (String [] args) {try {ObjectOutputStream objectOutputStream = new ObjectOutputStream (new FileOutputStream ("user.txt")); User user = new User (22, "Lao Tian"); objectOutputStream.writeObject (user) } catch (IOException e) {e.printStackTrace ();} @ Override public void writeExternal (ObjectOutput out) throws IOException {/ / write name to the binary stream StringBuffer reverse = new StringBuffer (name). Reverse (); out.writeObject (reverse); out.writeInt (age) } @ Override public void readExternal (ObjectInput in) throws IOException, ClassNotFoundException {/ / reverses the read string and assigns a value to the name instance variable this.name = ((StringBuffer) in.readObject ()) .reverse () .toString (); / / pays the read int type value to age this.age = in.readInt () }}
Perform serialization, then deserialization again, output:
Be careful
The Externalizable interface is different from the Serializable interface, to implement this interface, you must implement two methods in the interface to implement custom serialization, which is mandatory; in particular, you must provide a no-parameter constructor for public, because you need to reflect the creation object during deserialization.
Comparison of the two ways
The following figure shows a comparison of the two implementation methods:
Is there only two ways to serialize?
Of course not. According to the definition of serialization, it can be called serialization in any way, as long as you can convert the object in memory into a way that can be stored or transferred, and then restore it in turn. Therefore, our commonly used Fastjson, Jackson and other third-party class libraries to convert objects into Json format files can also be regarded as a kind of serialization, using JAXB to achieve XML format file output, can also be regarded as serialization. Therefore, do not be limited by thinking, in fact, we have carried out a lot of serialization and deserialization operations, involving different forms, data formats and so on.
Serialization algorithm
All objects saved to disk have a serialization code number.
When a program tries to serialize an object, it first checks whether the object has been serialized, and serializes the object into a byte sequence output only if the object has never been serialized (in this virtual machine).
If the object has been serialized, you can simply output the number.
Custom serialization
Sometimes we have a requirement that certain properties do not need to be serialized. Use the transient keyword to select fields that do not need to be serialized.
Continue to modify with the previous code, adding transient decorations to the age field:
Package com.tian.my_code.test.clone; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; public class User implements Serializable {private transient int age; private String name; public User () {} public User (int age, String name) {this.age = age This.name = name;} public int getAge () {return age;} public void setAge (int age) {this.age = age;} public String getName () {return name } public void setName (String name) {this.name = name;} public static void main (String [] args) {try {ObjectOutputStream objectOutputStream = new ObjectOutputStream (new FileOutputStream ("user.txt")); User user=new User (22, "Lao Tian"); objectOutputStream.writeObject (user) } catch (IOException e) {e.printStackTrace ();} ```serialize, and then deserialize:``` java package com.tian.my_code.test.clone; import java.io.* Public class SeriTest {public static void main (String [] args) {try {ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("user.txt")); User user= (User) ois.readObject (); System.out.println (user.getName ()); System.out.println (user.getAge ()) } catch (Exception e) {e.printStackTrace ();}
Run the output:
We can see from the output that using transient-decorated properties, this field is ignored when Java serializes, so the deserialized object, the property modified by transient is the default value.
For reference types, the value is the null; base type, the value is the 0-position Boolean type, and the value is false.
Explore
At this point, the serialization content is over, but if you stay at this level, you can't deal with the problems in the actual work.
For example, what if the model object holds references to other objects, and if the reference type is a more complex collection type?
If the String reference type is held in the above User, serialization is fine, but what if it is our custom reference class?
For example, the following scenario:
Package com.tian.my_code.test.clone; public class UserAddress {private int provinceCode; private int cityCode; public UserAddress () {} public UserAddress (int provinceCode, int cityCode) {this.provinceCode = provinceCode; this.cityCode = cityCode;} public int getProvinceCode () {return provinceCode } public void setProvinceCode (int provinceCode) {this.provinceCode = provinceCode;} public int getCityCode () {return cityCode;} public void setCityCode (int cityCode) {this.cityCode = cityCode;}}
Then add an attribute of UserAddress to User:
Package com.tian.my_code.test.clone; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; public class User implements Serializable {private static final long serialVersionUID =-2445226500651941044L; private int age; private String name; private UserAddress userAddress Public User () {} public User (int age, String name) {this.age = age; this.name = name;} / / get set public static void main (String [] args) {try {ObjectOutputStream objectOutputStream = new ObjectOutputStream (new FileOutputStream ("user.txt")) User user=new User (22, "Lao Tian"); UserAddress userAddress=new UserAddress (10001pm 10001001); user.setUserAddress (userAddress); objectOutputStream.writeObject (user);} catch (IOException e) {e.printStackTrace ();}
Run the above code:
A java.io.NotSerializableException exception was thrown. It is obvious that UserAddress does not implement a serialization interface. After the UserAddress class implements the serialization interface:
Package com.tian.my_code.test.clone
Import java.io.Serializable
Public class UserAddress implements Serializable {
Private static final long serialVersionUID = 5128703296815173156L
Private int provinceCode
Private int cityCode
Public UserAddress () {
}
Public UserAddress (int provinceCode, int cityCode) {
This.provinceCode = provinceCode
This.cityCode = cityCode
}
/ / get set
}
Run again, normal do not report wrong.
Deserialization code:
Package com.tian.my_code.test.clone; import java.io.*; public class SeriTest {public static void main (String [] args) {try {ObjectInputStream ois = new ObjectInputStream (new FileInputStream ("user.txt")); User user= (User) ois.readObject (); System.out.println (user.getName ()) System.out.println (user.getAge ()); System.out.println (user.getUserAddress (). GetProvinceCode ()); System.out.println (user.getUserAddress (). GetCityCode ());} catch (Exception e) {e.printStackTrace ();}
Running result:
Typical application scenario
Public final class String implements java.io.Serializable, Comparable, CharSequence {private static final long serialVersionUID =-6849794470754667710L;} public class HashMap extends AbstractMap implements Map, Cloneable, Serializable {private static final long serialVersionUID = 362498820763181265L;} public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable {private static final long serialVersionUID = 8683452581122892189L;}.
Many common classes implement serialization interfaces.
Expand again
The transient deserialization mentioned above is the default value, but you will find that several commonly used collection classes such as ArrayList, HashMap, LinkedList and other data storage fields are all modified by transient. However, in practice, the data we store with collection types can be serialized and deserialized normally.
Of course, the truth is still in the source code. In fact, each collection type has a separate implementation for serialization and deserialization, and does not use the default way of the virtual machine. Here we take the serialization and deserialization source code in ArrayList as an example:
Private void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException {int expectedModCount = modCount; / / serialize the non-transient and non-static fields s.defaultWriteObject () in the current ArrayList; / / serialize the actual number of s.writeInt (size) in the array; / / serialize the values in the array one by one to serialize for (int item0) I 0) {/ / capacity calculation int capacity = calculateCapacity (elementData, size); SharedSecrets.getJavaOISAccess () .checkArray (s, Object [] .class, capacity); / / check whether an array expansion operation ensureCapacityInternal (size) is required; Object [] a = elementData / / deserialize the values in the array for (int item0; I) sequentially
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.