Usually we are in Java memory object, is unable to do IO operation or network communication, because in the IO operation or network communication, people do not know what the memory object is a thing, so the object must be expressed in some way, that is, the state of the storage object. A Java object is represented in a variety of ways, and Java itself provides a way for the user to represent an object, which is serialization. In other words, serialization is just one way to represent an object. OK, with serialization, then there must be deserialization, so let's take a look at the meaning of serialization and deserialization.
Serialization: converts an object into a string of binary representations of byte arrays, which are persisted by saving or transferring the byte data.
Deserialization: reconstructs an array of bytes into an object.
Default serialization
Serialization only needs to implement the Java.io.Serializable interface. There is a serialversionuid parameter when serializing, and theJava serialization mechanism verifies version consistency by judging the serialversionuid of the class at run time. In the case of deserialization, the Java virtual Opportunity compares the Serialversionuid in the stream of bytes passed to the serialversionuid of the local corresponding entity class, and if the same entity class is considered consistent, it can be deserialized, Otherwise, the Java virtual Opportunity refuses to deserialize the entity class and throws an exception. There are two ways to build Serialversionuid:
1, the default 1L
2. Generate a 64-bit hash field based on class name, interface name, member method, and attributes.
If an entity class that implements the Java.io.Serializable interface does not explicitly define a variable named Serialversionuid, type Long, the Java serialization The mechanism will automatically generate a serialversionuid based on the compiled. class file, and if the. class file does not change, the serialversionuid will not change even if it is compiled more than once. In other words,Java defines the default serialization, deserialization method for the user, is actually the Defaultwriteobject method of ObjectOutputStream and the Defaultreadobject method of ObjectInputStream. See an example:
1PublicClass SerializableobjectImplementsSerializable2{3PrivateStaticFinalLong Serialversionuid = 1L;45PrivateString STR0;6PrivateTransientString str1;7Privatestatic String str2 = "abc";89PublicSerializableobject (String str0, String str1)10{11THIS.STR0 =STR0;12THIS.STR1 =str1;13}14 15 public String getStr0 () 16 {return Str0; }19 20 public String getStr1 () 21 {22 return str1; 23 }24}
1PublicStaticvoid Main (string[] args)ThrowsException2{3 File File =New File ("D:" + file.separator + "S.txt");4 OutputStream OS =NewFileOutputStream (file);5 ObjectOutputStream Oos =NewObjectOutputStream (OS);6 Oos.writeobject (New Serializableobject ("Str0", "str1")); Oos.close (); 8 9 InputStream is = new FileInputStream (file); 10 ObjectInputStream ois = new ObjectInputStream (is); Span style= "color: #008080;" >11 serializableobject so = (Serializableobject) ois.readobject (); 12 System.out.println ("STR0 =" + SO.GETSTR0 ()); SO.GETSTR1 ()); Ois.close ()
Do not run first, use a binary viewer to view the S.txt file, and explain the contents of each section in detail.
The 1th part is the serialized file header
◇ac ed:stream_magic Serialization Protocol
◇00 05:stream_version Serialization Protocol version
◇73:tc_object declares this to be a new object
The 2nd part is the description of the class to serialize, here is the Serializableobject class
◇72:tc_classdesc statement here begins a new class
◇00 1F: Decimal 31, which indicates that the length of the class name is 31 bytes
◇63 6F 6D ... 65 63 74: means "com.xrq.test.SerializableObject" this string of characters, you can count it is really 31 bytes
◇00 xx 01:serialversion, serialized id,1
◇02: Tag number that declares that the object supports serialization
◇00 01: The class contains 1 of the total number of domains
The 3rd part is the description of each property item in the object
◇4C: The character "L", which indicates that the property is an object type and not a basic type
◇00 04: Decimal 4, indicating the length of the property name
◇: String "STR0", property name
◇74:tc_string, representing a new string, referencing the object with a string
Part 4 is the information of the parent class of the object, without which the parent class does not have this part. It's like the 2nd part of the parent class.
◇00 12: Decimal 18, indicating the length of the parent class
◇4C 6A 61 ... 6E 3 B: "l/java/lang/string;" Represents the parent class property
◇78:tc_endblockdata, object block end flag
◇70:tc_null, stating that there are no other super-class flags
The 5th part is the actual value of the property item of the output object, and if the property item is an object, the object is also serialized here, as in the 2nd part of the rule.
◇00 04: Decimal 4, length of the attribute
◇: String "STR0", Str0 property value
From the above for the parsing of the serialized binary file, we can draw the following key conclusions:
1. The class information is saved after serialization
2. Attributes declared as transient will not be serialized, which is the function of the transient keyword
3. The property declared as static will not be serialized, as the problem can be understood, the serialization holds the state of the object, but the static modified variable belongs to the class and not to the variable, so serialization does not serialize it
Next run the code above to see
STR0 =null
Because STR1 is a variable of type transient, it is not serialized, so the deserialization is not anything, and the null displayed is consistent with our conclusion.
To specify the serialization process manually
Java does not force the user to use the default serialization method, the user can also according to their own preferences to specify their own desired serialization----as long as you can ensure that the serialization of the data before and after the need to be able to. The rules for manually specifying serialization methods are:
When serializing and deserializing, the virtual opportunity first attempts to invoke the WriteObject and ReadObject methods in the object, making the user-defined serialization and deserialization. If there is no such method, then the default call is ObjectOutputStream's Defaultwriteobject and ObjectInputStream's Defaultreadobject method. In other words, using the custom WriteObject method and the ReadObject method, users can control the process of serialization and deserialization themselves.
This is very useful. Like what:
1, some scenes, some fields we do not want to use Java to provide us with the serialization method, but want to be in a custom way to serialize it, such as ArrayList Elementdata, HashMap table (as to why the reason is explained when you write these two classes later), you can serialize them by declaring them as transient and then using the way you want them in WriteObject and ReadObject.
2, because the serialization is not safe, so some scenarios we need to encrypt some sensitive fields and then serialize, and then deserialize the same way to decrypt, to a certain extent, to ensure the security. To do this, you have to write your own writeobject and Readobject,writeobject methods to encrypt fields before serialization, ReadObject method decrypts the field after serialization
The above example serializobject this class, and the main function does not need to be modified:
1PublicClass SerializableobjectImplementsSerializable2{3PrivateStaticFinalLong Serialversionuid = 1L;45PrivateString STR0;6PrivateTransientString str1;7Privatestatic String str2 = "abc";89PublicSerializableobject (String str0, String str1)10{11THIS.STR0 =STR0;12THIS.STR1 =str1;13}1415PublicString GETSTR0 ()16{17ReturnSTR0;18}1920PublicString getStr1 ()21st{22Returnstr1;23}2425Privatevoid WriteObject (Java.io.ObjectOutputStream s)ThrowsException26{SYSTEM.OUT.PRINTLN ("I want to control the process of serialization");28S.defaultwriteobject ();29S.writeint (Str1.length ());30for (int i = 0; I < str1.length (); i++)31S.writechar (Str1.charat (i));32}3334Privatevoid ReadObject (Java.io.ObjectInputStream s)ThrowsException35{SYSTEM.OUT.PRINTLN ("I want to control the deserialization process myself."));37 S.defaultreadobject (); 38 int length = S.readint (); 39 char["cs = new char[length]; for (int i = 0; i < length; I++) 41 Cs[i] = S.readchar (); str1 = new String (cs, 043 }44}
Look directly at the results of the operation
I want to control the serialization process myself I want to control the process of deserialization STR0 = str0str1 = str1
See, the program went to our own written writeobject and ReadObject, and the transient modified STR1 also successfully serialized, deserialized----because the STR1 was written to the file and read from the file. Look again at the binary of the S.txt file:
See the orange part of the WriteObject method added str1 content. Now, summarize the usual usage of writeobject and readobject:
The object is serialized, deserialized, and then appended to the end of the file by the Defaultwriteobject and Defaultreadobject methods, and the additional content that needs to be read is read from the end of the file.
A summary of complex serialization scenarios
Although the serialization of Java can guarantee the persistence of object state, it is difficult to deal with some complex object structures, and finally a summary of some complex object situations:
1, when the parent class inherits the serializable interface, all subclasses can be serialized
2, the subclass implements the Serializable interface, the parent class does not have, the attribute in the parent class cannot be serialized (no error, data loss), but the attribute in the subclass can still be serialized correctly
3, if the serialized property is an object, then this object must also implement the Serializable interface, otherwise it will error
4, when deserializing, if the object's properties are modified or truncated, then the modified part of the property will be lost, but will not error
5, when deserializing, if the Serialversionuid is modified, the deserialization will fail
Java Object Representation 1: serialization, deserialization, and transient of keywords