In-depth analysis of "Java Fundamentals" serialization and deserialization

Source: Internet
Author: User
Tags object serialization shallow copy

First, preface

Review the process of serialization and deserialization of basic Java knowledge points, and organize the following learning notes.

Second, why serialization and deserialization is required

When the program runs, as long as necessary, the object can always exist, and we can access some of the object's state information at any time, if the program terminates, then the object will certainly not exist, but sometimes we need to terminate the program to save the state information of the object, then the program can be re-run to restore to the previous state, such as, When players play the game exit, they need to save the player's status information (such as level, equipment, etc.), then the player will log in again, you must restore the status information. We can use the database to achieve the purpose of this save state, in Java, we have a more convenient way to deal with, that is, serialization and deserialization. Serialization is a means of object persistence, in contrast to serialization, which is reassembled into objects through serialized information. Serialization and deserialization are widely used in the network transmission, RMI and other scenarios.

Iii. Overview of serialization

3.1 Serialization class structure diagram

The following shows the structure diagram of the classes related to serialization

Description: A dashed box represents an interface type, and a solid wireframe represents a specific class.

3.2 Description of the serialization keyword

The key words related to serialization are as follows

Description

1. Keyword transient, used to modify the field, indicates that this field will not be processed during the default serialization process, but it can be handled by another means.

2. The keyword Serialversionuid, which represents the serialized version number, allows deserialization when the serialization ID of two classes is consistent, by default it can take the value 1L provided by the compiler.

3.3 Description of serialization methods

The methods associated with serialization are as follows

Description: The WriteObject and ReadObject methods are declared in the ObjectOutput interface and the ObjectInput interface respectively, and are implemented in ObjectOutputStream and ObjectInputStream.

Iv. Serializable

4.1 Serializable definition

Serializable is defined as follows

Public interface Serializable {}

Description: Serializable is an interface and does not have any fields and methods, just as an identity.

4.2 Instructions for use

When serializing an object, you only need to mark the object as serializable, i.e. implement the interface serializable. The following person class implements the serializable interface.

View Code

The friend field of the person class is set to transient, indicating that it will not be serialized, and after the person class is defined, we can serialize and deserialize the person class with the following code:

View Code

The operation results are as follows

Name = LEESF, gender = man, age = $, friend info is [name = dyd, gender = woman, age = $, friend info is [null]]name = l EESF, gender = man, age = $, friend info is [null]

Description: Because the friend field is marked as transient, the default serialization operation is not serialized and its value is null after deserialization.

4.3 Problem description

1. The person class does not implement the Serializable interface

If the person class does not implement the serializable interface, what happens when it is serialized, the following exception occurs.

Exception in thread "main" java.io.notserializableexception:****

Indicates that the person does not implement the serializable interface for the following reasons

After calling the WriteObject method, a series of calls are passed, and the specific call stack is as follows

Description: Intercepts a piece of code in the WriteObject0 function, and you can see whether the object is a serializable type, or not, and throws an exception.

2. Handling Transient objects

When a field is transient decorated, it will not be processed with the default serialization mechanism, but if you want to serialize the transient field, you can add writeobject and ReadObject methods to the class that you want to serialize, with the method signature as follows

private void WriteObject (ObjectOutputStream stream) throws ioexceptionprivate void ReadObject (ObjectInputStream stream ) throws IOException, ClassNotFoundException

Note: Notice that writeobject and readobject are decorated with the private modifier, stating that this method can only be called in other methods of the class and cannot be called in other classes. So when calling ObjectOutputStream's WriteObject method, how to call this method to execute the user-defined processing logic, the answer is reflection. Reflection can be used in other classes to invoke private methods in this class, and the reflection is very powerful.

Using this method, we modify the person class as follows

View Code

The code of the test class is not modified and the result is as follows

Name = LEESF, gender = man, age = $, friend info is [name = dyd, gender = woman, age = $, friend info is [null]]name = l EESF, gender = man, age = $, friend info is [name = dyd, gender = woman, age = $, friend info is [null]]

Description: When implementing custom logic, the Defaultwriteobject () method can be called in the WriteObject method to implement the default serialization (serialization of non-transient fields) and can handle the transient keyword separately In the ReadObject method, the Defaultreadobject () method can be called to implement the default deserialization, and the transient keyword (which needs to be assigned) can be processed separately. It is worth noting that the logic of defaultwriteobject and handling transient keywords in the WriteObject method must be consistent with the logical order of defaultreadobject and processing transient keywords in readobject , otherwise an exception will be thrown.

After calling the WriteObject method, a series of calls are passed, and the specific call stack is as follows

Description: After reflection, the WriteObject method that is defined in the person class is eventually called. The invocation of the ReadObject method can be used in this analogy, no longer burdensome.

Wu, externalizable

In addition to serializing using the Serializable interface, you can use the Externalizable interface for serialization.

5.1 externalizable Definition

Externalizable is defined as follows

Public interface Externalizable extends java.io.Serializable {    void writeexternal (ObjectOutput out) throws IOException;    void Readexternal (ObjectInput in) throws IOException, ClassNotFoundException;}

Description: Externalizable implemented the serializable interface, and added two methods writeexternal and readexternal, the class needs to be serialized to implement the Externalizable interface, And rewrite the two methods defined in the interface.

5.2 Instructions for use

The serialized class is first implemented with the Externalizable interface and the Writeexternal and Readexternal methods are overridden, and the processing logic is implemented in both methods. We define the person class as follows

View Code

Description: The person class implements the Externalizable interface, overrides the Writeexternal and Readexternal methods, and implements user-defined serialization and deserialization logic. The test class code does not change, and the result is as follows:

Name = LEESF, gender = man, age = $, friend info is [name = dyd, gender = woman, age = $, friend info is [null]]name = l EESF, gender = man, age = $, friend info is [name = dyd, gender = woman, age = $, friend info is [null]]

Description: The serialization and deserialization process was successfully performed from the results. It is important to note that we have to provide a parameterless constructor for the person class to properly complete the serialization and deserialization process. Otherwise, the following exception will be thrown

Modify the person class as follows

View Code

Description: Provides a constructor for a parameter, without a parameterless constructor, to modify the test class code as follows

View Code

The operation results are as follows

Name = LEESF, gender = man, age = $, friend info is [name = dyd, gender = woman, age = $, friend info is [null]]exceptio N in thread "main" Java.io.InvalidClassException:com.hust.grid.leesf.serializable.Person; No valid constructor at    java.io.objectstreamclass$exceptioninfo.newinvalidclassexception ( objectstreamclass.java:150) at    java.io.ObjectStreamClass.checkDeserialize (objectstreamclass.java:768)    At Java.io.ObjectInputStream.readOrdinaryObject (objectinputstream.java:1775) at    Java.io.ObjectInputStream.readObject0 (objectinputstream.java:1351) at    Java.io.ObjectInputStream.readObject ( objectinputstream.java:371) at    Com.hust.grid.leesf.serializable.SerializableDemo.main (Serializabledemo.java : 32)

Note: In the deserialization process throws an exception, it can be seen that the person class does not have a legitimate constructor, the legitimate constructor refers to the parameterless constructor. When a parameterless constructor is provided, it can be run correctly.

5.3 Problem Description

1. Externalizable,writeobject and ReadObject methods

If the person class implements the Externalizable interface, and the WriteObject and ReadObject methods are added to the person class, which method is used when serializing and deserializing, modify the person class as follows

View Code

Description: A print statement was added to the method so that it was easy to determine which way to use. The test class code is as follows

View Code

Run results

Use writeexternal methoduse writeexternal methodname = leesf, gender = mans, age = $, friend info is [name = dyd, gender = Woman, age = A, friend info is [null]]use readexternal methoduse readexternal methodname = leesf, gender = mans, age = 24 , friend info is [name = dyd, gender = woman, age = $, friend info is [null]]

Note: From the results can be seen, is the Externalizable interface defined in the two methods for serialization and deserialization, then the reader may have another question, that is why print two times? The answer is because the method was called two times because the person class has a person field, which causes the call to be made two times.

2. Working with transient fields

You can implement custom logic in Writeexternal and Readexternal methods to serialize and deserialize transient fields.

VI. Serialization Issues

6.1 With the default serialization mechanism, will the static fields of the class be serialized?

When serializing with the default serialization mechanism, the static fields of the class are serialized, the static fields of the class are not serialized, and of course we can use custom serialization logic to serialize the static variables.

6.2 Parent Class serialization issues

When serializing a subclass with the default serialization mechanism, will the fields of its parent class be serialized? Can be divided into the following situations

1. The parent class does not implement the serializable interface and does not provide a default constructor

At this point, deserialization will go wrong, suggesting that the correct constructor is not provided. Modify the person class with the following code

View Code

The code for the test class is as follows

View Code

Run results

Number = 1, name = LEESF, gender = man, age = A, friend info is [number = 2, name = dyd, gender = woman, age = $, friend info is [null]]exception in thread "main" Java.io.InvalidClassException:com.hust.grid.leesf.serializable.Person; No valid constructor at    java.io.objectstreamclass$exceptioninfo.newinvalidclassexception ( objectstreamclass.java:150) at    java.io.ObjectStreamClass.checkDeserialize (objectstreamclass.java:768)    At Java.io.ObjectInputStream.readOrdinaryObject (objectinputstream.java:1775) at    Java.io.ObjectInputStream.readObject0 (objectinputstream.java:1351) at    Java.io.ObjectInputStream.readObject ( objectinputstream.java:371) at    Com.hust.grid.leesf.serializable.SerializableDemo.main (Serializabledemo.java : 32)

Description: You can see that there is no legal constructor provided.

2. The parent class does not implement the Serializable interface, providing a default constructor

In the first step there was an error, and we modified the person class with the following code

View Code

Description: Provides a parameterless constructor to the human class. The test class code does not change and the result is as follows

Number = 1, name = LEESF, gender = man, age = A, friend info is [number = 2, name = dyd, gender = woman, age = $, friend info is [null]]number = 0, name = LEESF, gender = man, age = $, friend info is [null]

Note: At this point, we can see that deserialization is possible, but the number field of the parent class is assigned the default value of int 0,person the transient field of the class is not serialized.

3. Parent class implements Serializable interface

When the parent class implements the Serializable interface, modify the person class code as follows

View Code

The code for the test class does not change, and the result is as follows

Number = 1, name = LEESF, gender = man, age = A, friend info is [number = 2, name = dyd, gender = woman, age = $, friend info is [null]]number = 1, name = LEESF, gender = man, age = $, friend info is [null]

Note: From the results, it is possible to make the correct serialization and deserialization, and the transient field of the subclass is not serialized.

6.3 Shared object Serialization issues

When a serialized two object contains a reference to another object, does the other object only appear once when deserializing? Modify the person class code as follows

View Code

The test class code is as follows

View Code

The operation results are as follows

[Email protected], [email protected], [email protected] [Email protected], [email protected], [email protected] [Email protected], [email protected], [email protected]

Note: From the results, oos1 execution of the writeobject is to write to the same memory space two times, from the results can be seen, two times the object is written to the address space is the same, that is, a shallow copy. The writeobject performed by Oos2 is written to another memory space, as shown in the results, because the object's address is different from the previous object address, which is a deep copy.

Vii. Summary

Write here, about the serialization and deserialization mechanism in Java has been analyzed, after this analysis, the understanding of the serialization mechanism is more profound. Learning a point of knowledge, it is necessary to recognize the earnest, a solid understanding of a knowledge point, blogging is a particularly good way. Thank you for watching the Garden friends ~

Reference links

http://blog.csdn.net/jiangwei0910410003/article/details/18989711/

http://www.hollischuang.com/archives/1140

  

  

In-depth analysis of "Java Fundamentals" serialization and deserialization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.