Serialization and Deserialization in Java: Understanding Object Persistence

Learn about Serialization and Deserialization in Java, processes that allow objects to be written to and read from byte streams. Discover how these features, used in frameworks like Hibernate and JMS, enable platform-independent data storage and transfer. Find out how to implement them using writeObject() and readObject() methods.



Serialization and Deserialization in Java

Serialization in Java writes the state of an object into a byte-stream, used in Hibernate, RMI, JPA, EJB, and JMS. Deserialization converts byte-stream back into an object. This process is platform-independent.

To serialize an object, use writeObject() method of ObjectOutputStream class. To deserialize, use readObject() method of ObjectInputStream class. The object class must implement the Serializable interface.

Advantages of Java Serialization

It allows object state to travel over the network (marshalling).

Serializable Interface

Serializable is a marker interface (no methods or fields). It marks classes so their objects can be serialized. Cloneable and Remote are also marker interfaces. The String class and wrapper classes implement Serializable by default.

Student.java

    import java.io.Serializable;  
    public class Student implements Serializable {  
        int id;  
        String name;  
        public Student(int id, String name) {  
            this.id = id;  
            this.name = name;  
        }  
    }  
    

ObjectOutputStream Class

Used to write primitive data types and Java objects to an OutputStream. Objects must support Serializable interface.

Constructor

public ObjectOutputStream(OutputStream out) throws IOException

Important Methods

  • public final void writeObject(Object obj) throws IOException - Writes an object.
  • public void flush() throws IOException - Flushes the output stream.
  • public void close() throws IOException - Closes the output stream.

ObjectInputStream Class

Deserializes objects and primitive data written by ObjectOutputStream.

Constructor

public ObjectInputStream(InputStream in) throws IOException

Important Methods

  • public final Object readObject() throws IOException, ClassNotFoundException - Reads an object.
  • public void close() throws IOException - Closes the input stream.

Example of Java Serialization

This example serializes a Student object and saves it to f.txt.

Persist.java

    import java.io.*;    
    class Persist {    
        public static void main(String args[]) {    
            try {    
                Student s1 = new Student(211, "ravi");    
                FileOutputStream fout = new FileOutputStream("f.txt");    
                ObjectOutputStream out = new ObjectOutputStream(fout);    
                out.writeObject(s1);    
                out.flush();    
                out.close();    
                System.out.println("success");    
            } catch(Exception e) {
                System.out.println(e);
            }    
        }    
    }    
    
Output

    success
    

Example of Java Deserialization

This example reads the data from the deserialized Student object.

Depersist.java

    import java.io.*;  
    class Depersist {  
        public static void main(String args[]) {  
            try {  
                ObjectInputStream in = new ObjectInputStream(new FileInputStream("f.txt"));  
                Student s = (Student) in.readObject();  
                System.out.println(s.id + " " + s.name);  
                in.close();  
            } catch(Exception e) {
                System.out.println(e);
            }  
        }  
    }  
    
Output

    211 ravi
    

Serialization with Inheritance

If a class implements Serializable, all its subclasses will also be serializable.

SerializeISA.java

    import java.io.Serializable;    
    class Person implements Serializable {    
        int id;    
        String name;    
        Person(int id, String name) {    
            this.id = id;    
            this.name = name;    
        }    
    }    
    
    class Student extends Person {    
        String course;    
        int fee;    
        public Student(int id, String name, String course, int fee) {    
            super(id, name);    
            this.course = course;    
            this.fee = fee;    
        }    
    }    
    
    public class SerializeISA {    
        public static void main(String args[]) {    
            try {    
                Student s1 = new Student(211, "ravi", "Engineering", 50000);    
                FileOutputStream fout = new FileOutputStream("f.txt");    
                ObjectOutputStream out = new ObjectOutputStream(fout);    
                out.writeObject(s1);    
                out.flush();    
                out.close();    
                System.out.println("success");    
            } catch(Exception e) {
                System.out.println(e);
            }    
            try {    
                ObjectInputStream in = new ObjectInputStream(new FileInputStream("f.txt"));    
                Student s = (Student) in.readObject();    
                System.out.println(s.id + " " + s.name + " " + s.course + " " + s.fee);    
                in.close();    
            } catch(Exception e) {
                System.out.println(e);
            }    
        }    
    }  
    
Output

    success
    211 ravi Engineering 50000
    

Serialization with Aggregation

If a class has a reference to another class, all referenced classes must be serializable. Otherwise, NotSerializableException is thrown.

Address.java

    class Address {    
        String addressLine, city, state;    
        public Address(String addressLine, String city, String state) {    
            this.addressLine = addressLine;    
            this.city = city;    
            this.state = state;    
        }    
    }  
    
Student.java

    import java.io.Serializable;  
    public class Student implements Serializable {  
        int id;  
        String name;  
        Address address; // HAS-A relationship
        public Student(int id, String name) {  
            this.id = id;  
            this.name = name;  
        }  
    }  
    

Since Address is not Serializable, serialization will fail.

Serialization with Static Data Member

Static data members are not serialized because they belong to the class, not the object.

Employee.java

    class Employee implements Serializable {  
        int id;  
        String name;  
        static String company = "SSS IT Pvt Ltd"; // Not serialized
        public Student(int id, String name) {  
            this.id = id;  
            this.name = name;  
        }  
    }  
    

Serialization with Array or Collection

All objects within an array or collection must be serializable. Otherwise, serialization will fail.

Externalizable Interface

The Externalizable interface allows objects to be serialized in a custom format. It has two methods:

  • public void writeExternal(ObjectOutput out) throws IOException
  • public void readExternal(ObjectInput in) throws IOException

Transient Keyword

If a field is marked as transient, it will not be serialized.

Employee.java

    class Employee implements Serializable {  
        transient int id;  
        String name;  
        public Student(int id, String name) {  
            this.id = id;  
            this.name = name;  
        }  
    }  
    

When deserialized, id will have its default value (0 for int).

SerialVersionUID

SerialVersionUID is used to verify the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. It is recommended to declare SerialVersionUID explicitly.

Employee.java

    import java.io.Serializable;    
    class Employee implements Serializable {    
        private static final long serialVersionUID = 1L;    
        int id;    
        String name;    
        public Student(int id, String name) {    
            this.id = id;    
            this.name = name;    
        }    
    }