Initial knowledge of serialization and deserialization
1 Overview
Serialization refers to the process of transforming the state information of an object into a form that can be stored or transmitted During serialization, an object writes its current state to temporary or persistent storage The object can be recreated later by reading or deserializing the state of the object from the store
Serialization: use ObjectOutputStream to convert the information of the object into a string of byte values in a fixed format, output them and save them to disk for a long time
Deserialization: use ObjectInputStream to read the previously serialized data in the disk and restore it into an object
2 features / application scenarios
- The files to be serialized must implement the Serializable interface to enable the serialization function
- Data that does not need to be serialized can be modified into static. Reason: static resources belong to class resources and are not output with the object being serialized
- Each serialized file has a unique id. if this id is not added, the compiler will automatically calculate and generate one according to the class definition information
- During deserialization, if it is inconsistent with the serialized version number, deserialization cannot be completed
- Commonly used data transmission with the server, serialization into a file, deserialization to read data
- Socket streams are commonly used to pass objects between hosts
- Data that does not need to be serialized can also be modified as transient (temporary), which only exists in memory during program operation and will not be serialized and persisted
3. Flow objects involved
Serialization: ObjectOutputStream
ObjectOutputStream writes the basic data types of Java objects to OutputStream, and the persistent storage of objects can be realized by using files in the stream. If the stream is a network socket stream, you can refactor the object on another host or in another process.
Construction method:
ObjectOutputStream(OutputStream out)
Creates an ObjectOutputStream that writes to the specified OutputStream
General method:
writeObject(Object obj)
Writes the specified object to ObjectOutputStream
Deserialization: ObjectInputStream
ObjectInputStream deserializes and reconstructs the basic data and objects previously written using ObjectOutputStream.
Construction method:
ObjectInputStream(InputStream in) creates an ObjectInputStream read from the specified InputStream
General method:
readObject() reads objects from ObjectInputStream
4 code to realize serialization and deserialization
4.1 step 1: create Student class
Create package: CN tedu. serializable
Create class: student java
package cn.tedu.serializable; import java.io.Serializable; /**This class is used to encapsulate student classes*/ /** * If this class wants to complete serialization, it must implement a serializable interface, otherwise an error will be reported: * Error message: Java io. NotSerializableException: cn. tedu. serializable. Student * Serializable Interface is an empty interface without any method. It is used as a flag. This class can be serialized / deserialized * */ public class Student implements Serializable{ /**Each serialized file needs to be assigned a unique UID value*/ //The serializable class Student does not declare a static final serialVersionUID field of type long //private static final long serialVersionUID = 1L; private static final long serialVersionUID = -3193364654654535741L; //1. Define the relevant attributes of students + private encapsulation private String name;//full name private int age;//Age private String addr;//address private char gender;//Gender /**Automatically create construction method: right click -- > source -- > generate constructor using fields*/ //2. Create parameterless structure -- parameterless structure must be provided manually, otherwise it will be overwritten by parameterless structure public Student() { System.out.println("I am Student Nonparametric structure of"); } //3. Create full parameter structure public Student(String name,int age,String addr,char gender) { super();//The default calls the parameterless construction of the parent class this.name = name; this.age = age; this.addr = addr; this.gender = gender; System.out.println("I am Student All parameter structure of"); } //4. After attribute encapsulation, this class needs to provide public attribute access and setting methods get() & set() /**Automatically create get() & set(), right click -- > source -- > generate getters and setters*/ public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } //Print result: CN tedu. serializable. Student@4c873330 -->Address value //You want to see the attribute value of the object because you want to view the attribute of the serialized object. You need to override toString() //5. Rewrite toString() //Auto generate toString() -- right click -- > source -- > generate toString() @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", addr=" + addr + ", gender=" + gender + "]"; } }
4.2 step 2: create a serialized test class
Create package: CN tedu. serializable
Create class: testserializable java
package cn.tedu.serializable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /**This class is used to serialize and deserialize test classes*/ //Serialization: refers to the process of permanently storing java objects in the program in the disk, which is equivalent to writing out. The direction is out -- > objectoutputstream //Deserialization: refers to the process of reading / restoring the data stored in the serialized file to the java program. The direction is in -- > objectinputstream public class TestSerializable { public static void main(String[] args) { //method();// This method is used to complete the function of serialization method2();//This method is used to complete the deserialization function } /**Deserialization method*/ public static void method2() { //Declare local variables that are effective in this method. Local variables need to be initialized, and the default value is null ObjectInputStream in = null; try { //1. Create ObjectInputStream stream stream object to complete deserialization in = new ObjectInputStream(new FileInputStream("D://ready//1.txt")); //2. Generate the specified object by deserializing the stream object Object o = in.readObject(); System.out.println(o); System.out.println("Congratulations!Deserialization succeeded!"); } catch (Exception e) { System.out.println("I'm sorry!Deserialization failed!"); e.printStackTrace(); } finally {//A block of code that must be executed writes code that releases resources try { //3. Release resources in.close(); } catch (IOException e) { e.printStackTrace(); } } } /**Serialization method*/ public static void method() { //Declare local variables that are effective in this method. Local variables need to be initialized, and the default value is null ObjectOutputStream out = null; try { //1. Create ObjectOutputStream stream object to complete serialization out = new ObjectOutputStream(new FileOutputStream("D://ready//1.txt")); //2. Specify the object to serialize (output) Student obj = new Student("Spongebob",3,"Bottom of the sea",'male'); //3. Serialize the output Student object through OOS stream object out.writeObject(obj); System.out.println("congratulations!Serialization succeeded!"); } catch (IOException e) { System.out.println("I'm sorry!Serialization failed!"); e.printStackTrace(); }finally {//The operation of closing the flow should be put in finally {} -- because this code block will be executed try { //4. Shut down operation out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
5 test error NotSerializableException:
Error reason: the class of the object to be serialized does not implement the serialization interface
Solution: implement serialization interface
6 test error InvalidClassException:
Error reason: the UID used in this deserialization does not match the UID used in serialization
Solution: the UID during deserialization should be consistent with that during serialization, or a sequence operation corresponds to a deserialization operation during testing, otherwise an error will be reported if it does not match
Note: the prompt for automatically generating serialVersionUID is set in IDEA:
7 Why does the deserialization version number need to be consistent with the serialization version number?
During deserialization, the JVM will compare the serialVersionUID in the deserialized stream with the serialVersionUID in the corresponding entity class during serialization. If it is inconsistent, it cannot be deserialized normally, and an exception InvalidClassException with inconsistent serialization version occurs.
Moreover, when defining the entity class that needs to be serialized, if we do not add UID manually,
The Java serialization mechanism will automatically generate one according to the compiled class, so only the class generated in the same compilation is the same UID.
If we add UID manually, as long as the value is not modified, we can serialize and deserialize regardless of the number of compilations.