A Deep Dive into Serialization and Deserialization: Principles, Applications, and Best Practices

What is serialization and deserialization of objects

Serialization refers to the process of converting objects into a byte stream for storage or transmission over the network.
Deserialization is the process of converting a byte stream into an object and restoring the state of the original object.

In computer science, serialization and deserialization are common data processing techniques used to transfer objects or persist the state of objects between different systems and different programming languages.
Insert image description here

Serialization steps

1. Create an output stream: write the object into the output stream.
2. Object encoding: Convert object data into byte stream form, and you can use different encoding methods (such as binary encoding, JSON, XML, etc.).
3. Output to target: Output the encoded byte stream to the target location, such as file, memory, network, etc.

Deserialization steps

1. Create an input stream: read a byte stream from the input stream.
2. Object decoding: Decode the byte stream into the data form of the original object.
3. Construct the object: Use the decoded data to construct the object and restore the state of the object.

Case presentation

In Java, serialization and deserialization are implemented by implementing the Serializable interface.
To serialize, you need to follow these steps:
Make sure the class implements the java.io.Serializable interface.
Create an output stream (such as java.io.FileOutputStream) to write objects to a file or network stream.
Create a java.io.ObjectOutputStream object and connect it to the output stream.
Use the writeObject() method of ObjectOutputStream to write the object to the output stream.

Sample code looks like this:

public class SerializationExample {
    
    
    public static void main(String[] args) {
    
    
        MyClass obj = new MyClass(); // 要进行序列化的对象

        try {
    
    
            FileOutputStream fileOut = new FileOutputStream("data.ser"); // 序列化的目标文件
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(obj); // 将对象写入输出流
            out.close();
            fileOut.close();
            System.out.println("对象已被序列化并保存为 data.ser");
        } catch(IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

To deserialize, you need to follow the following steps:
1. Create an input stream (such as java.io.FileInputStream) to read the serialized object.
2. Create a java.io.ObjectInputStream object and connect it to the input stream.
3. Use the readObject() method of ObjectInputStream to read the object from the input stream and return an object of type Object.
Convert the returned object to the required type (for example, cast to a concrete class).
Sample code looks like this:

public class DeserializationExample {
    
    
    public static void main(String[] args) {
    
    
        MyClass obj = null;
        
        try {
    
    
            FileInputStream fileIn = new FileInputStream("data.ser"); // 读取序列化的文件
            ObjectInputStream in = new ObjectInputStream(fileIn);
            obj = (MyClass) in.readObject(); // 从输入流中读取对象并转换类型
            in.close();
            fileIn.close();
        } catch(IOException e) {
    
    
            e.printStackTrace();
            return;
        } catch(ClassNotFoundException e) {
    
    
            e.printStackTrace();
            return;
        }
        
        System.out.println("对象已成功反序列化");
        // 对反序列化后的对象进行操作
        // ...
    }
}

Which fields cannot be serialized in Java

In Java, some fields cannot be serialized. These fields include:

  • Static variables: Static variables belong to the class level, not the instance level. They are not contained in any specific object and therefore cannot be serialized.
  • Transient variables: Variables modified with the transient keyword will not be serialized. Transient variables are typically used to represent temporary state or sensitive information and are thus ignored during serialization.
  • Methods: In Java, methods cannot be serialized. Only the object's data state can be serialized and deserialized.
  • Anonymous inner classes and local inner classes: Both anonymous inner classes and local inner classes contain references to outer classes, which can cause problems during serialization.
  • The type is the functional interface type in the java.util.function package. Since functional interfaces usually have lambda expressions or method references, they cannot be serialized.

It should be noted that if a class implements the Serializable interface but contains non-serializable fields, the values ​​of these fields will be ignored when serializing an instance of the class. If you need to serialize these fields, you can do it through a custom serialization process.

In order to prevent certain fields from being serialized, you can use the transient keyword to modify these fields so that they are ignored during the serialization process. For example:

public class MyClass implements Serializable {
    
    
    private transient int transientField;  // transient字段,在序列化时被忽略

    // 其他字段和方法...
}

When using the transient keyword to control the serialization behavior of fields, there are several aspects that need to be paid attention to:
Serialization version compatibility: When you modify the class, especially when it comes to fields that need to be serialized, you need to pay attention to the serialization version. compatibility. Version incompatibilities may cause exceptions or data loss when deserializing a serialized object. It is recommended to add a serialVersionUID field to the class and update it appropriately when the class is modified to ensure version compatibility during deserialization.

The importance of serialization and deserialization

  • It can realize cross-platform and cross-language data exchange, allowing data to be shared between different systems.
  • Data persistence can be performed to save objects to storage media so that they can be read and used again.
  • Can be used for remote calls to transfer objects to a remote system over the network and restore them to objects on the remote system for processing.
  • In different programming languages, corresponding serialization and deserialization mechanisms or libraries are usually provided so that developers can easily implement object serialization and deserialization operations.

Serialization and deserialization application scenarios

  • Security control of sensitive data: When using the transient keyword to mark a field, please ensure that it does not contain sensitive information, such as passwords, keys, etc. Fields modified by transient will be ignored after the object is serialized, which can avoid leakage of sensitive data.
  • Custom serialization logic: In some cases, you may need to customize the serialization and deserialization logic of objects. You can implement a custom serialization process by implementing the writeObject() and readObject() methods. In this case, you can manually control the serialization behavior of the field in these methods, even if the field is modified as transient.
  • Cross-platform compatibility: If your application needs to run on different platforms or interact with other languages, be sure to pay attention to cross-platform compatibility issues. Some platforms or languages ​​may handle the transient keyword differently, so you need to be careful when doing cross-platform or cross-language serialization operations.

In short, when using the transient keyword, you must carefully consider the serialization behavior of the object and the characteristics of the corresponding framework. Ensure version compatibility, security controls, and cross-platform compatibility to ensure the correctness and stability of serialization operations.

Guess you like

Origin blog.csdn.net/qq_54796785/article/details/133170720