Java Serialization using Serializable Interface


As you know serialization is general technique or process to store in-memory objects into some persistent format. For doing this Java provides interface and classes, by using these you can serialize and de-serialize object very easily.

Serializable marker Interface ObjectInputStream and ObjectOutputStream main things which you have to use to do serialization and de-serialization in Java.

So let’s start with one simple example, we have one UserInfo class has three fields and one of the field is marked transient.

Class which i want to serialize

public class UserInfo {
    private String user;
    private transient String password;
    private int id;

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String toString() {
        return "user:" + user + " password: " + password + " email: " + id;
    }
}

For serializing any object we need to write that object into ObjectOutputStream.writeObject(Object object) method. Obviously first you need to associate ObjectOutputStream with some OutputStream where you want to store objects.

For de-serializing any object we need to read object from Object ObjectInputStream.readObject() method. Obviously first you need to associate ObjectInputStream with some InputStream from where you want to read object.

Code to serialize and de-serialize object into file

public class Test {
    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUser("Anupama");
        userInfo.setPassword("password");
        userInfo.setId(1001);
        serialize(userInfo);

        userInfo = (UserInfo) deserialize();
        System.out.println("After desialization using Serializable");
        System.out.println(userInfo);

    }

    private static void serialize(Object obj) {
        try {
            FileOutputStream fileOut = new FileOutputStream("userinfo.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(obj);
            out.close();
            fileOut.close();
            System.out.println(obj);
            System.out.println("Serialized data is saved in userinfo.ser");
        } catch (IOException i) {
            i.printStackTrace();
        }
    }

    private static Object deserialize() {
        Object obj = null;
        try {
            FileInputStream fileIn = new FileInputStream("userinfo.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            obj = in.readObject();
            in.close();
            fileIn.close();

        } catch (IOException i) {
            i.printStackTrace();
            return null;
        } catch (ClassNotFoundException c) {
            System.out.println("UserInfo class not found");
            c.printStackTrace();
            return null;
        }
        return obj;
    }

In above code in created object of UserInfo class and set values to files and tried to serialize it but it throw an exception java.io.NotSerializableException at out.writeObject(obj);. This exception is because of i did\’t use Serializable marker interface in UserInfo class. Serializable marker interface is used to tell ObjectOutputStream that this class can be serialized as ObjectOutputStream check given object is design to serialize or not as in many cases some developer don\’t want that any one can serialize it\’s complete class and for this there can be many reasons like what kind of private variables he used to impletent his class.

So it is clear that for serializing any object using ObjectOutputStream object must implement Serializable marker interface as other serialization interface like Externalizable extends Serializable.

Now implement Serializable marker inteface UserInfo class and try to serialize

public class UserInfo implements Serializable{
...
}

It will give following output

user:Anupama password: password email: 1001
Serialized data is saved in userinfo.ser
After desialization using Serializable
user:Anupama password: null email: 1001

In above output you can see after deserialization password is null, this is because i marked password field in UserInfo class transient. This is to indicate ObjectOutputStream class that do not serialize fields which are marked transient.

So till now it clear that it will serialize all fields of class public, protected, private and not transient, what about static fields?

What is behavior of constructor?

There is no role of constructors at the time of serialization and deserialization when serializing using default serialization method provided by java. Note in case base class is not marked Serializable then default constructor of base class will be call at the time of de-serialization.

What is behavior of final fields?

Final fields are treated normal fields.

Try to find out what happens to static fields

Create a new class Statics as given below

public class Statics implements Serializable {
    public static int VALUE1= 10;
    public static int VALUE2= 20;
    
    public String toString()
    {
        return "VALUE1: "+VALUE1+" VALUE2: "+ VALUE2;
    }
}

Now test it using following code in above main function

public static void main(String[] args) {
    Statics statics = new Statics();
    serialize(statics);
    // Change static values
    Statics.VALUE1 = 100;
    Statics.VALUE2 = 200;
    // de-serialize old value
    statics = (Statics) deserialize();
    System.out.println("After desialization using Serializable");
    System.out.println(statics);

}

Below is output

VALUE1: 10 VALUE2: 20
Serialized data is saved in statics.ser
After desialization using Serializable
VALUE1: 100 VALUE2: 200

After seeing above output it is clear that ObjectOutputStreamnever serialize static or static final by default for Serializable type objects

Inheritance and Serialization

If base class is not marked Serializable then field of base class will not serialize and during de-serialization it will invoke default constructor of base classes and desterilize on classes marked Serializable .