Java serialization Serializable (detailed example)
1. What is serialization and deserialization?
Serialization is a process of describing objects in a series of bytes. deserialization is a process of recreating these bytes into an object.
2. Under what circumstances should serialization be performed?
A) when you want to save the objects in the memory to a file or database;
B) when you want to use a socket to transmit objects over the network;
C) when you want to transmit objects through RMI;
3. How to Implement serialization
You can implement the Serializable interface for the classes to be serialized. The Serializable interface does not have any methods. It can be understood as a tag, indicating that the class can be serialized.
4. serialization and deserialization examples
If we want to serialize an object, we first need to create some OutputStream (such as FileOutputStream and ByteArrayOutputStream), and then encapsulate these outputstreams in an ObjectOutputStream. In this case, you only need to call the writeObject () method to serialize the object and send it to OutputStream.(Remember: Object serialization is byte-based. character-based hierarchies such as Reader and Writer cannot be used.). In the reverse sequence process (restoring a sequence to an object), you need to encapsulate an InputStream (such as FileInputstream and ByteArrayInputStream) in ObjectInputStream and then call readObject.
Package com. sheepmu; import java. io. fileInputStream; import java. io. fileNotFoundException; import java. io. fileOutputStream; import java. io. IOException; import java. io. objectInputStream; import java. io. objectOutputStream; import java. io. serializable; public class MyTest implements Serializable {private static final long serialVersionUID = 1L; private String name = "SheepMu"; private int age = 24; public static void main (String [] args) {// the following code serializes try {ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("my. out "); // The Name Of The output stream is my. out; ObjectOutputStream can output the Object into Byte stream MyTest myTest = new MyTest (); oos. writeObject (myTest); oos. flush (); // buffer stream oos. close (); // close the stream} catch (FileNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace () ;}fan (); // call the following deserialization code} public static void fan () // The deserialization process {ObjectInputStream oin = null; // The local variable must initialize try {oin = new ObjectInputStream (new FileInputStream ("my. out ");} catch (FileNotFoundException e1) {e1.printStackTrace ();} catch (IOException e1) {e1.printStackTrace ();} MyTest mts = null; try {mts = (MyTest) oin. readObject (); // The Object is transformed down to the MyTest Object} catch (ClassNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace ();} System. out. println ("name =" + mts. name); System. out. println ("age =" + mts. age );}}
A my. out file is generated in the workspace of this project. The serialized content will be completed later. First, the output after deserialization is as follows:
Name = SheepMu
Age = 24
5. serialization ID
Serialization ID provides two generation policies in Eclipse. One is fixed 1L, and the other is random generation of a non-repeated long type data (actually generated using JDK ), we recommend that you use the default 1L if there is no special requirement. This ensures that deserialization is successful when the code is consistent. This may also be the cause of serialization and deserialization failure, because serialization and deserialization cannot be performed between different serialization IDs.
6. Relationship between objects before and after serialization
Is it "=" or equal? Or is it light replication or deep replication?
Answer: The object address after deserialization and restoration is different from the original address in deep replication.
The address of the object before and after serialization is different, but the content is the same, and the reference contained in the object is also the same. In other words, through serialization, we can achieve "deep copy" for any Serializable object -- this means that we copy the entire object network, it is not just a basic object and its reference. For objects of the same stream, their addresses are the same, indicating that they are the same object, but they are different from the object addresses of other streams. That is to say, as long as the object is serialized to a single class, we can restore the same object network as we write, and as long as the same class, the object is the same.
7. serialization of static variables
If you add static before the age variable in the above Code, the output is still
Name = SheepMu
Age = 24
But let's look at the example below:
Package com. sheepmu; import java. io. fileInputStream; import java. io. fileNotFoundException; import java. io. fileOutputStream; import java. io. IOException; import java. io. objectInputStream; import java. io. objectOutputStream; import java. io. serializable; public class MyTest implements Serializable {private static final long serialVersionUID = 1L; private String name = "SheepMu"; private static int age = 24; public stat Ic void main (String [] args) {// the following code serializes try {ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream ("my. out "); // The Name Of The output stream is my. out; ObjectOutputStream can output the Object into Byte stream MyTest myTest = new MyTest (); oos. writeObject (myTest); oos. flush (); // buffer stream oos. close (); // close the stream} catch (FileNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace ();} fan (); // call the following deserialization code} public Static void fan () {new MyTest (). name = "SheepMu_1 ";//!!!!!!!!!!!!!!!! Focus on the changes in these two lines age = 1 ;//!!!!!!!!!!!!!!!!!!! The change part of these two rows is ObjectInputStream oin = null; // The local variable must initialize try {oin = new ObjectInputStream (new FileInputStream ("my. out ");} catch (FileNotFoundException e1) {e1.printStackTrace ();} catch (IOException e1) {e1.printStackTrace ();} MyTest mts = null; try {mts = (MyTest) oin. readObject (); // The Object is transformed down to the MyTest Object} catch (ClassNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace ();} System. out. println ("name =" + mts. name); System. out. println ("age =" + mts. age );}}
Output result:
Name = SheepMu
Age = 1
Why does the age variable in the above Code still be deserialized 24 after being added to static? The new Code for assigning values to variables is not static to get the serialization value, but static to get the new value. Cause:Serialization ignores static variables, that is, serialization does not save the status of static variables.Static members belong to the class level, so they cannot be serialized. That is, the object state is serialized, not the class state. The meaning of serialization is that the serialization information does not contain this static member domain. The reason why static is added at the top is still output 24 because the value is allocated when JVM loads the class. Note:The variables after transient cannot be serialized.But the situation is a little complicated.
8. Summary:
A) when a parent class is serialized, the Child class automatically serializes without explicitly implementing the Serializable interface;
B) when the instance variable of an object references other objects, the referenced object is also serialized when the object is serialized;
C) static and transient variables cannot be serialized;