See www.jianshu.com/p/4935a8797…

Overview: In order to be able to save directly as a Java object in a program and then retrieve that Java object, serialization capability is required. Serialization can be thought of as a mechanism for converting the state of a Java object into a medium acceptable form in a format for easy storage or transfer. If you think about it, you can get a sense of the basic flow. When you serialize, you save the class information, attributes, attribute values, and so on related to a Java object. When you deserialize, you build the Java object from this information. The process may involve references to other objects, so information about the objects referenced here is also involved in serialization.

Serialization in Java requires the Serializable or Externalizable interfaces.

Serialization functions:

  • Provides a simple and extensible object save recovery mechanism.
  • For remote calls, objects can be easily encoded and decoded, just like direct object transfer.
  • Objects can be persisted to the medium, just like implementing direct object storage.
  • Allows objects to customize the format of external storage.

When serialization is required: It is certain that serialization is required at storage time. Serialization, as you know, is a way to stream an object, and we sometimes feel like we’re not serializing in our project, we’re just storing it, so the idea that objects need to be serialized in order to be stored seems to be neutered from there. What is the truth?

Let’s start with a common data type class declaration:

public final class String implements java.io.Serializable.Comparable<String>, CharSequence
public class Date implements java.io.Serializable.Cloneable.Comparable
Copy the code

Other types, such as int, long, and Boolean, are basic data types and have corresponding data structures in the database. From the above class declaration, we think that serialization is not done, but it is the specific data types that help us to achieve serialization when declaring different variables. If the variables of the entity class already help us serialize, why should we show that the class implements serializable interface?

Note what I said above: First, serialization has two purposes. First, it is easy to store and second, it is easy to transfer. When our general entity class does not need programmers to implement serialization again, please think about two questions: first: is there a corresponding data structure in the storage media? Second: does this entity class require a remote transfer (or call between two different systems or even distributed modules)?

Freeze () serialization (vARCHAR, int, etc.); freeze (freeze, freeze); If not, and we do need to store it, when should the programmer not serialize the object?

Note: If you open the Serializable interface source code, you will find that the Serializable interface is null, so who implements the serialization operation? In fact, if you look at the interface annotations, when we make the entity class implement the Serializable interface, we are telling the JVM that this class can be serialized by the default serialization mechanism.

Then, it should be noted that when we look at the entity class declaration implementing the Serializable interface, we see that these classes need to be called remotely. That is, it needs or may need to be called remotely, which is where serialization for transport comes in.

Serialization case: father.java

public class Father {
    public int f;
}
Copy the code

Son.java

public class Son extends Father implements Serializable {
    public int s;
    public Son(a) {
        super();
    }
}
Copy the code

SerializableMain.java

public class SerializableMain {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // If a serialized object is changed to a parent class, an exception is thrown and no interface is marked Serializable
// Father father = new Father();
        Father father = new Son();
        father.f = 5;
        / / the serialization
        FileOutputStream fileOutputStream  = new FileOutputStream("temp.o");
        ObjectOutput objectOutputStream = new ObjectOutputStream(fileOutputStream);
        objectOutputStream.writeObject(father);
        // deserialize
        FileInputStream fileInputStream = new FileInputStream("temp.o");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        Object object = objectInputStream.readObject();
        Father f = (Father) object;
        // Since the subclass does not have the f variable, it is the f variable of the calling parent classSystem.out.println(f.f); }}Copy the code

F = 0, f = 5 when the parent implements Serializable interface. Therefore, serialization interfaces should be explicitly implemented in entity beans.

Serialization fields: Which fields of the class participate in serialization during serialization? There are actually two ways to determine which fields will be serialized,

  • By default, non-static and non-transient fields in Java objects are defined as fields that require a sequence.
  • Another approach is to declare the objects that the class needs to serialize through an ObjectStreamField array.

As you can see, common fields are serialized by default. For some fields that contain sensitive information, we do not want them to participate in the serialization, so the simplest way is to declare the field transient.

(Note: transient keyword declaration modified fields do not participate in serialization)

How do I use ObjectStreamField? As an example, the User class has id, name, age, and address fields, and only serializes name and AGE fields through ObjectStreamField array declarations. There’s no need to worry about why this is the way it’s declared, it’s just the convention.

public class User implements Serializable {

    private int id;
// Transient tag fields do not participate in serialization
// private transient String name;
    private String name;
    private int age;
    private String address;
    
    private static final ObjectStreamField[] serialPersistentFields = {
            new ObjectStreamField("name", String.class),
            new ObjectStreamField("age", Integer.class) }; . }Copy the code