1, Overview
- serialize
- The objects in the program are stored directly in the form of files according to the sequence of objects in memory
- Deserialization
- Reread the object data from the file into the program
- Is to read out the previously serialized object from the file and change it into an object again
- Reread the object data from the file into the program
- In 2018, java officials found that at least 1 / 3 of the bug s in the program were caused by the use of serialization and deserialization technology. If this serialization security problem cannot be replaced by more appropriate technology, serialization technology will not be eliminated in the short term, otherwise the whole java ecology will be affected
2, Implement serialization
1. Serializable interface implements serialization
- To implement serialized classes, you need to implement the Serializable interface and use the object output stream ObjectOutputStream
- This is a tag interface
- In the underlying source code, ObjectOutputStream will judge whether the written object is a string, or use instanceof to judge whether it is Serializable or its implementation class. If these conditions are not met, an exception will be thrown
- Using ObjectOutputStream requires an OutputStream object to be passed in
- If a class that implements the Serializable interface wants to be serialized, all properties must also implement the Serializable interface, otherwise it cannot be serialized
2. Four ways to realize partial attribute serialization
- Modifying attributes with transient
- The premise is that this class implements the Serializable interface
- Attributes modified by transient are not serialized
- Using the static modifier
- The premise is that this class implements the Serializable interface
- Attributes modified by static are not serialized
- Use the default methods writeObject and readObject
- These two methods are defined in a class that implements the Serializable interface
- Both methods must be private void modifier, otherwise it will not take effect
- The writeObject method is used to customize the content and order of serialization
- The readObject method is used to customize the content and order of deserialization, which should be consistent with the content order of the writeObject method
- Implement Externalizable interface
- The Externalizable interface inherits from the Serializable interface
- Two methods need to be overridden
- writeExternal
- Input parameter ObjectOutput out
- Use out.writeObject (property name) to specify the property to be serialized
- readExternal
- Input ObjectInput in
- Use in.readObject() to obtain the property value after deserialization, which should be consistent with the sequence of serialized properties
- writeExternal
3. Examples
a. Properties that validate transient and static modifiers cannot be serialized
Properties that validate transient and static modifiers cannot be serialized
- Define the Person class and implement the Serializable interface. among
- a attribute is decorated with transient (unable to be serialized), b attribute is decorated with static (unable to be serialized), and c attribute is defined normally (can be serialized)
package SerializableTest; import java.io.Serializable; public class Person implements Serializable { //Cannot be serialized using transient decoration private transient String a; private static String b; private String c; @Override public String toString() { return "Person{" + "a='" + a + '\'' + ", b='" + b + '\'' + ", c='" + c + '\'' + '}'; } public String getA() { return a; } public void setA(String a) { this.a = a; } public static String getB() { return b; } public static void setB(String b) { Person.b = b; } public String getC() { return c; } public void setC(String c) { this.c = c; } }
- Define serialization tool classes
package SerializableTest; import java.io.*; public class SerializableUtils { //Serialization operation public static void mySerializable(Object obj,String fileName) throws IOException { FileOutputStream fos = new FileOutputStream(fileName); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(obj); oos.close(); fos.close(); } //Deserialization operation public static Object myDesSerializable(String fileName) throws IOException, ClassNotFoundException { FileInputStream fis = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(fis); Object o = ois.readObject(); return o; } }
- Define test class
package SerializableTest; import java.io.IOException; public class test { public static void main(String[] args) throws IOException, ClassNotFoundException { Person p = new Person(); p.setA("A"); Person.setB("B"); p.setC("C"); System.out.println("Before serialization p Object:"+p); //Person{a='A', b='B', c='C'} //Serialization operation SerializableUtils.mySerializable(p,"I:\\a.txt"); //Modifying the value of b attribute will not affect the value of b attribute in a.txt file Person.setB("bbbb"); //Deserialization operation Object o = SerializableUtils.myDesSerializable("I:\\a.txt"); if (o instanceof Person){ p = (Person) o; } //B is static modified. If it can be serialized, the result should still be B, but the result here is bbb, indicating that static modification cannot be serialized //A is null, indicating that the a attribute was not serialized during the serialization operation System.out.println("Serialized p Object:"+p); //Person{a='null', b='bbbb', c='C'} } }
- After testing, it is found that the attributes modified by transient and static cannot be instantiated
b. Verify that the serialized properties are specified using the default methods writeObject and readObject
Verify that the serialized properties are specified using the default methods writeObject and readObject
- The Serializable interface is implemented by default
- Rewrite the Person class so that a and b are serialized and c is not serialized
package SerializableTest; import java.io.IOException; import java.io.Serializable; public class Person implements Serializable { //Cannot be serialized using transient decoration private String a; private String b; private String c; private void writeObject(java.io.ObjectOutputStream out) throws IOException { //Serialize a and b attributes, not c attributes System.out.println("writeObject Serialization processing..."); out.writeObject(a); out.writeObject(b); } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { //Deserialization reads the values of the a and b attributes System.out.println("readObject Deserialize..."); a = (String) in.readObject(); b = (String) in.readObject(); } @Override public String toString() { return "Person{" + "a='" + a + '\'' + ", b='" + b + '\'' + ", c='" + c + '\'' + '}'; } public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } public String getC() { return c; } public void setC(String c) { this.c = c; } }
- Tool class unchanged
- Test class
package SerializableTest; import java.io.IOException; public class test { public static void main(String[] args) throws IOException, ClassNotFoundException { Person p = new Person(); p.setA("A"); p.setB("B"); p.setC("C"); System.out.println("Before serialization p Object:"+p); //Person{a='A', b='B', c='C'} //Serialization operation SerializableUtils.mySerializable(p,"I:\\a.txt"); //Modifying the value of b attribute will not affect the value of b attribute in a.txt file p.setB("bbbb"); //Deserialization operation Object o = SerializableUtils.myDesSerializable("I:\\a.txt"); if (o instanceof Person){ p = (Person) o; } //B is static modified. If it can be serialized, the result should still be B, but the result here is bbb, indicating that static modification cannot be serialized //A is null, indicating that the a attribute was not serialized during the serialization operation System.out.println("Serialized p Object:"+p); //Person{a='null', b='bbbb', c='C'} } }
- test result
- It can be seen that c really cannot be serialized
c. Verify the serialization part properties of the Externalizable interface
Verify the serialization part properties of the Externalizable interface
- Modify the Person class, implement the Externalizable interface, and override the two methods
package SerializableTest; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; public class Person implements Externalizable { //Cannot be serialized using transient decoration private String a; private String b; private String c; @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println("writeExternal Serialize operation..."); out.writeObject(a); out.writeObject(b); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("readExternal Perform deserialization..."); a = (String) in.readObject(); b = (String) in.readObject(); } @Override public String toString() { return "Person{" + "a='" + a + '\'' + ", b='" + b + '\'' + ", c='" + c + '\'' + '}'; } public String getA() { return a; } public void setA(String a) { this.a = a; } public String getB() { return b; } public void setB(String b) { this.b = b; } public String getC() { return c; } public void setC(String c) { this.c = c; } }
- Tool classes remain unchanged
- Test class
package SerializableTest; import java.io.IOException; public class test { public static void main(String[] args) throws IOException, ClassNotFoundException { Person p = new Person(); p.setA("A"); p.setB("B"); p.setC("C"); System.out.println("Before serialization p Object:"+p); //Person{a='A', b='B', c='C'} //Serialization operation SerializableUtils.mySerializable(p,"I:\\a.txt"); //Modifying the value of b attribute will not affect the value of b attribute in a.txt file p.setB("bbbb"); //Deserialization operation Object o = SerializableUtils.myDesSerializable("I:\\a.txt"); if (o instanceof Person){ p = (Person) o; } //B is static modified. If it can be serialized, the result should still be B, but the result here is bbb, indicating that static modification cannot be serialized //A is null, indicating that the a attribute was not serialized during the serialization operation System.out.println("Serialized p Object:"+p); //Person{a='null', b='bbbb', c='C'} } }
- test result
- c is not serialized, indicating that the implementation of the Externalizable interface can also realize the serialization of some attributes
d. The difference between Serializable interface and Externalizable interface
difference | Serializable | Externalizable |
Implementation complexity | The implementation is simple, and java has built-in support | The implementation is complex and is completed by developers themselves |
Execution efficiency | All attributes are saved uniformly by java, with low performance | Developers can improve execution efficiency by deciding which attributes the object saves |
Occupied space | Large space for saving data | Partial storage, occupying relatively small space |
Frequency of use | high | Low |
3, Implement deserialization
- Read the previously serialized stored object from the file and change it into an object in the program again
- ObjectInputStream used
- An InputStream object needs to be passed in
- See the example of implementing serialization for an example