What are Serialized Sequencing Learning Notes

What are Java serialization and deserialization?

Serialization: Converts Java objects into ordered byte streams for transfer over the network or for saving in local files.
Deserialization: The process by which a client retrieves a serialized byte stream of an object from a file or network to restore the byte sequence to a Java object.

Why do I need to serialize and deserialize?

Brief description: For persistent or network transfer of in-memory objects, serialization and deserialization are required at this time

In-depth description:

  1. Object serialization implements distributed objects.

Primary applications such as RMI (Remote Method Invocation) use object serialization to run services on remote hosts, just like running objects on local machines.

  1. java object serialization not only preserves the data of one object, but also recursively holds the data of each object referenced by the object.

The entire object hierarchy can be written to a byte stream, saved in a file, or passed over a network connection. Object serialization allows "deep copy" of the object, that is, the object itself and the referenced object itself. Serializing an object may result in an entire object sequence.

  1. Serialization writes in-memory classes to a file or database.

For example, if you serialize a class and save it as a file, you can restore the original class to memory by deserializing the data in the file the next time you read it, or you can serialize the class to stream data for transmission.

Generally speaking, a class that has already been instantiated is converted to file storage, and the next time it needs to be instantiated, it can be instantiated into memory by simply deserializing, preserving all variables and states in the class at the time of serialization.

  1. Objects, files, and data have many different formats, which make it difficult to transfer and save them uniformly.

After serialization, they are all byte streams. Whatever they were, they can become the same thing. They can be transferred or saved in a common format. After the transfer is over, to be used again, they can be deserialized and restored so that the object or object, file or file can be used.

How does serialization work?

Implement the Serializable or Externalizable interfaces.

Serializable interface

All subtypes of serializable classes are serializable by themselves.

public interface Serializable {
}

What does an empty interface do?
The serialization interface has no methods or fields and is used only to identify Serializable semantics. When serializing, it determines whether the classes to be serialized are Enum, Array, and Serilizable types, and if they are not, throws NotSerializableException directly.

public class A1_User implements Serializable {
	private String name;
	private int age;
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}
	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 static void main(String[] args) throws FileNotFoundException {
		// Initializes The Object
		A1_User user = new A1_User();
		user.setName("xiaoming");
		user.setAge(18);
		System.out.println(user);

		// Write Obj to File
		try {
			ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
			oos.writeObject(user);
		} catch (IOException e1) {
			e1.printStackTrace();
		}

		// Read Obj from File
		File file = new File("tempFile");
		try {
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
			A1_User newUser = (A1_User) ois.readObject();
			System.out.println(newUser);
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

Result

User [name=xiaoming, age=18]
User [name=xiaoming, age=18]

Externalizable interface

Externalizable inherits from Serializable, which defines two abstract methods: writeExternal() and readExternal().

When using the Externalizable interface for serialization and deserialization, developers need to override the writeExternal() and readExternal() methods. Otherwise, the values of all variables become default values.

public class B1_User implements Externalizable {
	private String name;
	private int age;
	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 void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(name);
	}
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		name = (String) in.readObject();
	}
	@Override
	public String toString() {
		return "B1_User [name=" + name + ", age=" + age + "]";
	}
}
	public static void main(String[] args) {
		// Write Obj to file
		B1_User user = new B1_User();
		user.setName("LingLing");
		user.setAge(18);
		System.out.println(user);
		
		try {
			new ObjectOutputStream(new FileOutputStream("tempFile")).writeObject(user);
		} catch (IOException e) {
			e.printStackTrace();
		}

		// Read Obj from file
		File file = new File("tempFile");
		try {
			B1_User newInstance = (B1_User) new ObjectInputStream(new FileInputStream(file)).readObject();
			System.out.println(newInstance);
		} catch (IOException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

Result

B1_User [name=LingLing, age=18]
B1_User [name=LingLing, age=0]

Comparison of two serializations

Implement Serializable interfaceImplement Externalizable interface
The system automatically stores the necessary informationProgrammers decide what information to store
Java built-in support, easy to implement, simply implement the interface without any code supportTwo methods within an interface must be implemented
Slightly poorer performanceSlightly better performance

What is a serialVersionUID?

serialVersionUID is used to indicate compatibility between different versions of a class

Java's serialization mechanism verifies version consistency by determining the serialVersionUID of a class at run time.
When deserializing, the JVM compares the serialVersionUID in the incoming byte stream with the serialVersionUID of the corresponding local entity (class) and can deserialize if the same is considered consistent.
Otherwise, an exception with inconsistent serialization versions will occur.

Why should the value of the specified serialVersionUID also be displayed?

If the specified serialVersionUID is not displayed, the JVM automatically generates a serialVersionUID based on the attributes during serialization, serializes it with the attributes, and then persists or transports it over the network.
During deserialization, the JVM automatically generates a new version of the serialVersionUID based on attributes, then compares the new version of the serialVersionUID with the older version of the serialVersionUID generated at serialization. If the same, the deserialization succeeds or an error is reported.

If the display is specified, the JVM will still generate a serialVersionUID when serializing and deserializing, but the value is the value that we show, so that the new and old versions of the serialVersionUID are consistent when deserializing.

What can be the problem with not displaying the specified serialVersionUID in actual development?
If we don't modify our classes after they've been written, that's fine, but it's not possible in practice. Our classes iterate over and over, once they're modified for incompatibility.Checks are done during deserialization, and if not explicitly defined, a serialVersionUID is automatically generated based on the class name and attributes, and errors will occur if two serialVersionUIDs are different.So in actual development, we all show that specifying a serialVersionUID doesn't matter how much the value is, as long as it doesn't change.

When does the serialVersionUID change?

The Alibaba Java Development Manual contains the following provisions:
Why Alibaba requires programmers to carefully modify the values of the serialVersionUID field
serialVersionUID is used to verify version consistency.
Therefore, do not change the serialVersionUID value in the class when making compatibility upgrades.
Modify the serialVersionUID value if upgrade is completely incompatible to avoid deserialization clutter

What if some fields in Java serialization do not want to be serialized?

Use the transient keyword to modify variables that you do not want to serialize.

The purpose of the transient keyword is to control the serialization of a variable. Adding the keyword before a variable declaration prevents the variable from being serialized to a file. After being deserialized, the value of the transient variable is set to the initial value, such as int 0 and object null. Transients can only modify variables, not classes and methods.

Will static variables be serialized?

No. Because serialization is for objects, static variables take precedence over objects and are loaded as classes are loaded, they will not be serialized.

The serialVersionUID is also modified by static. Why is the serialVersionUID serialized?
The serialVersionUID attribute is not serialized. The JVM automatically generates a serialVersionUID when serializing the object, and assigns the value of the serialVersionUID attribute that we show as specified to the automatically generated serialVersionUID.

Tags: Java Database Hibernate

Posted on Thu, 09 Sep 2021 14:50:34 -0400 by aksival