Friday, 4 January 2019

Java Serialization and Customized Serialisation


  • Serialization
    • Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in memory. This mechanism is used to persist the object.
    • The byte stream created is platform independent. So, the object serialized on one platform can be deserialized on a different platform.
    • To make a Java object serializable we implement the java.io.Serializable interface.
    • The ObjectOutputStream class contains writeObject() method for serializing an Object.
    • The ObjectInputStream class contains readObject() method for deserializing an object.
  • readResolve()
    • This ensures that nobody can create another instance by serializing and deserializing the singleton.
  • Advantages of Serialization
    • To travel an object across a network.
    • To save/persist state of an object.

  • Only the objects of those classes can be serialized which are implementing java.io.Serializable interface. Serializable is a marker interface (has no data member and method). It is used to “mark” java classes so that objects of these classes may get certain capability.
  • Other examples of marker interfaces are:- Cloneable and Remote.
  • Points to remember
    •  If a parent class has implemented Serializable interface then child class doesn’t need to implement it but vice-versa is not true.
    • Only non-static data members are saved via Serialization process.
    • Static data members and transient data members are not saved via Serialization process.So, if you don’t want to save value of a non-static data member then make it transient.
    •  Constructor of object is never called when an object is deserialized.
  • SerialVersionUID
    • The Serialization runtime associates a version number with each Serializable class called a SerialVersionUID, which is used during Deserialization to verify that sender and reciever of a serialized object have loaded classes for that object which are compatible with respect to serialization. 
    • If the reciever has loaded a class for the object that has different UID than that of corresponding sender’s class, the Deserialization will result in an InvalidClassException. A Serializable class can declare its own UID explicitly by declaring a field name.
  • Example
    • // Java program to illustrate loss of information // because of transient keyword. import java.io.*; class GfgAccount implements Serializable { String username = "gfg_admin"; transient String pwd = "geeks"; } class CustomizedSerializationDemo { public static void main(String[] args) throws Exception { GfgAccount gfg_g1 = new GfgAccount(); System.out.println("Username : " + gfg_g1.username + " Password : " + gfg_g1.pwd); FileOutputStream fos = new FileOutputStream("abc.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); // writeObject() method present in GfgAccount class // will be automatically called by jvm oos.writeObject(gfg_g1); FileInputStream fis = new FileInputStream("abc.ser"); ObjectInputStream ois = new ObjectInputStream(fis); // readObject() method present GfgAccount class // will be automatically called by jvm GfgAccount gfg_g2 = (GfgAccount)ois.readObject(); System.out.println("Username : " + gfg_g2.username + " Password : " + gfg_g2.pwd); } } ############### OUTPUT ############### Username : gfg_admin Password : geeks Username : gfg_admin Password : null
  • Customized Serialisation
    • During serialization, there may be data loss if we use the ‘transient’ keyword. ‘Transient’ keyword is used on the variables which we don’t want to serialize. But sometimes, it is needed to serialize them in a different manner than the default serialization (such as encrypting before serializing etc.), in that case, we have to use custom serialization and deserialization.
    • Customized serialization can be implemented using the following two methods:
      • private void writeObject(ObjectOutputStream oos) throws Exception: 
        • This method will be executed automatically by the jvm(also known as Callback Methods) at the time of serialization. Hence to perform any activity during serialization, it must be defined only in this method.
      • private void readObject(ObjectInputStream ois) throws Exception:
        •  This method will be executed automatically by the jvm(also known as Callback Methods) at the time of deserialization. Hence to perform any activity during deserialization, it must be defined only in this method.
    • Example
      • import java.io.*; class GfgAccount implements Serializable { String username = "gfg_admin"; transient String pwd = "geeks"; // Performing customized serialization using the below two methods: // this method is executed by jvm when writeObject() on // Account object reference in main method is // executed by jvm. private void writeObject(ObjectOutputStream oos) throws Exception { // to perform default serialization of Account object. oos.defaultWriteObject(); // epwd (encrypted password) String epwd = "123" + pwd; // writing encrypted password to the file oos.writeObject(epwd); } // this method is executed by jvm when readObject() on // Account object reference in main method is executed by jvm. private void readObject(ObjectInputStream ois) throws Exception { // performing default deserialization of Account object ois.defaultReadObject(); // deserializing the encrypted password from the file String epwd = (String)ois.readObject(); // decrypting it and saving it to the original password // string starting from 3rd index till the last index pwd = epwd.substring(3); } } class CustomizedSerializationDemo { public static void main(String[] args) throws Exception { GfgAccount gfg_g1 = new GfgAccount(); System.out.println("Username :" + gfg_g1.username + " Password :" + gfg_g1.pwd); FileOutputStream fos = new FileOutputStream("abc.ser"); ObjectOutputStream oos = new ObjectOutputStream(fos); // writeObject() method on Account class will // be automatically called by jvm oos.writeObject(gfg_g1); FileInputStream fis = new FileInputStream("abc.ser"); ObjectInputStream ois = new ObjectInputStream(fis); GfgAccount gfg_g2 = (GfgAccount)ois.readObject(); System.out.println("Username :" + gfg_g2.username + " Password :" + gfg_g2.pwd); } } ############### OUTPUT ############### Username :gfg_admin Password :geeks Username :gfg_admin Password :geeks

No comments:

Post a Comment

Search This Blog

Contact us

Name

Email *

Message *