Serialization of
The goal of object serialization is to save the object to disk, or to allow the object to be transferred directly in the network. The object serialization mechanism allows the translation of in-memory Java objects into a platform-independent binary stream, allowing this binary stream to be persisted on disk, transmitted through the network to another network node, and once the other program obtains this binary stream, Can be said to restore the binary stream to the original Java object.
Why serialization exists
We know that when the virtual machine stops running, the objects in memory disappear, and the other is that the Java object is to be transferred over the network, such as parameters and return values in the RMI process. In both cases, the object must be converted to a byte stream, from either to disk space or to the network.
Because RMI is the foundation of Java EE Technology---All distributed applications require cross-platform, cross-network. Serialization is therefore the basis of Java EE, and it is generally recommended that each JavaBean class created by the program be serialized.
How to serialize
If you want each object to support a serialization mechanism, you must make its class serializable, and the class must implement one of the following two interfaces:
1, Serializable
2, Extmalizable
Here are a few principles that we'll look at together:
1, serializable is an indicative interface, there is no method or field defined in the interface, only used to mark the semantics of serializable.
2, static variables and member methods are not serializable.
3, a class to be able to be serialized, all reference objects in the class must also be serializable. Otherwise the entire serialization operation will fail, and a notserializableexception will be thrown unless we mark the non-serializable reference as transient.
4. Variables declared as transient are not stored by the serialization tool, nor are static variables stored.
First, take a look at the serialization of an object and store it in a file:
public class person implements serializable{ int Span style= "color: #000000;" > age; String address; double height; public person (int Age, String Address, double height) { this . Age = address; this . Height = height; }}
Public class serializabletest{ publicstaticvoidthrows IOException, IOException { new objectoutputstream (new fileoutputstream ( " D:/data.txt ")); New Person (+ "China"); Oos.writeobject (p); Oos.close (); }}
Execution Result:
1, the object is serialized, write a binary file, all open garbled is normal phenomenon, but through garbled we can still see the file is stored in the object that we created.
2, the person object implements the serializable interface, this interface does not have any method need to be implemented, just a markup interface, indicating that the object of this class can be serialized.
3. In this program, we are calling the WriteObject () method of the ObjectOutputStream object to output the serializable object. The object also provides methods for outputting the base type.
writeInt
writeUTF(String str)
writeFloat(float val)
Second, let's take a look at the process of deserializing an object from a file:
1 Public classserializabletest2 {3 Public Static voidMain (string[] args)throwsIOException, IOException,4 classnotfoundexception5 {6ObjectOutputStream Oos =NewObjectOutputStream (NewFileOutputStream (7"D:/data.txt"));8Person p =NewPerson (+, "China", 180);9 Oos.writeobject (p);Ten oos.close (); One AObjectInputStream Ois =NewObjectInputStream (NewFileInputStream ( -"D:/data.txt")); -person P1 =(person) ois.readobject (); theSystem.out.println ("age=" + P1.age + "; address=" +p1.address -+ "; height=" +p1.height);
Ois.close (); - } -}
Execution Result:
age=25;address=china;height=180.0
1, starting from line 12th is the process of deserialization. The input stream is ObjectInputStream, which corresponds to the previous objectoutputstream.
2, when calling the ReadObject () method, there is a strong turn of the action. So when deserializing, provide the class file that the Java object belongs to.
3. If multiple objects are written to a file using the serialization mechanism, they need to be read in the order in which they are actually written when deserializing.
Serialization of object references
1, the above describes the object's member variable is the basic data type, if the object's member variable is a reference type, what will be different?
The member variable of this reference type must also be serializable, otherwise the object of the class that owns the type member variable is not serializable.
2, in the reference to the object of this place, there will be a special situation. For example, there are two teacher objects, and their student instance variables refer to the same person object, and the person object has a reference variable that references it. As shown in the following:
There are three objects per, T1, T2, if all are serialized, there is a problem where the person object is implicitly serialized when serializing the T1. When serializing a T2, the person object is also implicitly serialized. When you serialize per, the person object is explicitly serialized. So when deserializing, you get three person objects, which causes T1, T2 to refer to the person object that is not the same . Obviously, this is not in line with the relationship shown in the diagram, but also against the original intent of the Java serialization.
To avoid this scenario, the Java serialization mechanism uses a special algorithm:
1. All objects saved to disk have a serialized number.
2 . When a program attempts to serialize an object, it first checks to see if the object has been serialized, and only if the object has never been serialized (in this virtual machine), the system will convert the object into a sequence of bytes and output.
3. If the object is already serialized, the program will output a serialized number instead of re-serialization.
Custom serialization
1, the previous introduction can use the transient keyword to decorate the instance variable, the variable will be completely isolated from the serialization mechanism. Or use the same procedure as before, just decorate the address variable with transient:
1 Public classPersonImplementsSerializable2 {3 intAge ;4 transientString address;5 Doubleheight;6 PublicPerson (intAge, String address,Doubleheight)7 {8 This. Age =Age ;9 This. Address =address;Ten This. Height =height; One } A}
1 Public classserializabletest2 {3 Public Static voidMain (string[] args)throwsIOException, IOException,4 classnotfoundexception5 {6ObjectOutputStream Oos =NewObjectOutputStream (NewFileOutputStream (7"D:/data.txt"));8Person p =NewPerson (+, "China", 180);9 Oos.writeobject (p);Ten oos.close (); One AObjectInputStream Ois =NewObjectInputStream (NewFileInputStream ( -"D:/data.txt")); -person P1 =(person) ois.readobject (); theSystem.out.println ("age=" + P1.age + "; address=" +p1.address -+ "; height=" +p1.height);
Ois.close (); - } -}
The result of serialization:
Deserialization results:
age=25;address=null;height=180.0
2. In the binary file, the word "China" is not seen, and the value of address after deserialization is null.
3. This shows that variables modified using tranisent, after serialization and deserialization, the Java object will lose the value of the instance variable.
In the light of the above, Java provides a custom serialization mechanism. This allows the program to control how each instance variable is serialized, even if it does not serialize the instance variable.
Classes that require special handling during serialization and deserialization should provide the following methods for implementing custom serialization.
WriteObject ()
ReadObject ()
These two methods do not belong to any classes and interfaces, as long as they are provided in the class to be serialized, they are automatically called in the serialization mechanism.
Where the WriteObject method is used to write the instance state of a particular class so that the corresponding ReadObject method can recover it. By overriding this method, the programmer can gain control over the serialization, and can autonomously determine which instance variables need to be serialized and serialized. The method calls Out.defaultwriteobject to hold the instance variables of the Java object, which enables the purpose of serializing the state of the Java object.
1 Public classPersonImplementsSerializable2 {3 /**4 * 5 */6 Private Static Final LongSerialversionuid = 1L;7 intAge ;8 String address;9 Doubleheight;Ten PublicPerson (intAge, String address,Doubleheight) One { A This. Age =Age ; - This. Address =address; - This. Height =height; the } - - //WriteObject method for JAVA Bean customization - Private voidWriteObject (ObjectOutputStream out)throwsIOException + { -SYSTEM.OUT.PRINTLN ("writeobejct------"); + Out.writeint (age); AOut.writeobject (NewStringBuffer (address). reverse ()); at out.writedouble (height); - } - - Private voidReadObject (ObjectInputStream in)throwsIOException, ClassNotFoundException - { -SYSTEM.OUT.PRINTLN ("readobject------"); in This. Age =in.readint (); - This. Address =((StringBuffer) In.readobject ()). Reverse (). toString (); to This. Height =in.readdouble (); + } -}
1 Public classserializabletest2 {3 Public Static voidMain (string[] args)throwsIOException, IOException,4 classnotfoundexception5 {6ObjectOutputStream Oos =NewObjectOutputStream (NewFileOutputStream (7"D:/data.txt"));8Person p =NewPerson (+, "China", 180);9 Oos.writeobject (p);Ten oos.close (); One AObjectInputStream Ois =NewObjectInputStream (NewFileInputStream ( -"D:/data.txt")); -person P1 =(person) ois.readobject (); theSystem.out.println ("age=" + P1.age + "; address=" +p1.address -+ "; height=" +p1.height); - ois.close (); - } +}
Serialization results:
Deserialization results:
1. The difference between this place and the previous one is to provide the WriteObject method and the ReadObject method in the person class, and provide a concrete implementation.
2. When ObjectOutputStream calls the WriteObject method execution, the WriteObject method of the person class is definitely called, because the log in line 20th in the code is output on the console.
3. The benefit of custom implementations is that programmers can be more granular or able to customize the serialization they want to implement, such as reversing the value of the address variable in an example. With this feature, we can do special processing of some sensitive information during the serialization process.
4, here because we provide these two methods in the class to serialize, so is called, if not provided, I think it will be called by default Objectoutputstream/objectinputstream the two methods provided.
Serialization issues
1. Static variables are not serialized.
2. When a subclass is serialized:
If the parent class does not implement the serializable interface and does not provide a default constructor, then the serialization of the subclass will be faulted;
If the parent class does not implement the Serializable interface and provides a default constructor, the subclass can be serialized and the member variables of the parent class will not be serialized.
If the parent class implements the Serializable interface, both the parent and child classes can be serialized.
Deep understanding of Java I/O series five: Object serialization