Tuesday, 6 October 2015

Serialization with Inheritance

If Super class is Serializable:
If super class is Serializable than all its sub-classes will be serializable by default. No need to implement the serializable interface in subclass explicitly.
If Superclass is not Serializable but subclass is:
If the superclass is not Serializable than to serialize the subclass’ object we must implement the serializable interface in subclass explicitly. In this case, the superclass must have a no-argument constructor in it.
If the superclass is serializable but we don’t want the subclass to be serialized:
To prevent a subclass from being serialized we must implement writeObject() and readObject() method and need to throw NotSerializableException from these methods.
Sometimes we need to extend a class that doesn’t implement the Serializable interface.
If we rely on the automatic serialization behavior and the superclass has some state, then they will not be converted to stream and hence not retrieved later on.
This is one place, where readObject() and writeObject() methods really help. By providing their implementation, we can save the superclass state to the stream and then retrieve it later on.
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectInputValidation;
import java.io.ObjectOutputStream;
import java.io.Serializable;

class SuperClass {
      private int id;
      private String value;
      public int getId() {
            return id;
      }
      public void setId(int id) {
            this.id = id;
      }
      public String getValue() {
            return value;
      }
      public void setValue(String value) {
            this.value = value;
      }
}

class SubClass extends SuperClass implements Serializable, ObjectInputValidation {
      private static final long serialVersionUID = -1322322139926390329L;
      private String name;
     
      @Override
      public String toString(){
            return "SubClass{id="+getId()+",value="
                     +getValue()+",name="+getName()+"}";
      }
     
      //adding helper method for serialization to save/initialize super class state
      private void readObject(ObjectInputStream ois)
                            throws ClassNotFoundException, IOException{
            ois.defaultReadObject();
            //notice the order of read and write should be same
            setId(ois.readInt());
            setValue((String) ois.readObject());
      }
     
      private void writeObject(ObjectOutputStream oos) throws IOException{
            oos.defaultWriteObject();
            oos.writeInt(getId());
            oos.writeObject(getValue());
      }
     
      @Override
      public void validateObject() throws InvalidObjectException {
            //validate the object here
            if(name == null || "".equals(name)) {
               throw new InvalidObjectException("name can't be null/empty");
            }
            if(getId() <=0) {
              throw new InvalidObjectException("ID can't be negative/zero");
            }
      }
      public String getName() {
            return name;
      }
      public void setName(String name) {
            this.name = name;
      }
}

class SerializationUtil {
      // deserialize to Object from given file
      public static Object deserialize(String fileName)
                           throws IOException, ClassNotFoundException {
            FileInputStream fis = new FileInputStream(fileName);
            ObjectInputStream ois = new ObjectInputStream(fis);
            Object obj = ois.readObject();
            ois.close();
            return obj;
      }
      // serialize the given object and save it to file
      public static void serialize(Object obj, String fileName)
                                            throws IOException {
            FileOutputStream fos = new FileOutputStream(fileName);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(obj);
            fos.close();
      }
}

public class TestSerialization {
      public static void main(String[] args) {
            String fileName = "subclass.ser";
            SubClass subClass = new SubClass();
            subClass.setId(10);
            subClass.setValue("Data");
            subClass.setName("Rajesh");
            try {
                  SerializationUtil.serialize(subClass, fileName);
            } catch (IOException e) {
                  e.printStackTrace();
                  return;
            }
            try {
                  SubClass subNew = (SubClass)
                            SerializationUtil.deserialize(fileName);
                  System.out.println("SubClass read = "+subNew);
            } catch (ClassNotFoundException e) {
                  e.printStackTrace();
            } catch (IOException e) {
                  e.printStackTrace();
            }
      }
}

Output:
SubClass read = SubClass{id=10,value=Data,name=Rajesh}

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...