Over a million developers have joined DZone.

What You Need to Know About Serialization

Get a good look at serialization, deserialization, and securing your serialized objects with this example code.

· Java Zone

What every Java engineer should know about microservices: Reactive Microservices Architecture.  Brought to you in partnership with Lightbend.

Are these questions puzzling you when you try to dig deeper into serialization?

  • What happens when final transient field gets serialized?

  • What happens when static transient or final static transient field gets serialized?

  • What happens to private members of a serializing class?

  • What if a super class or interface does not implement Serializable while the derived class is getting serialized?

  • How do I validate an object after serialization? Is it really important?

  • How to get auto generated or private serialversionuid while deserialization in progress?

  • What happens to non-serialized aggregated object i.e. object with "has-a" relationship?

Well, all these questions are going to be answered with a code example, but before that, let's get a feel for serialization.

In plain English, serialization is a process 'to arrange in a series and broadcast it to the outer world'. So in Java, we send a serializing object to the network stream and publish or send it to a directory to store its form for the future use.

Let's jump on an example to learn more. And if you want to know even more, be sure to check out the 'points to be noted' section. 

Employee.java

import java.io.InvalidObjectException;
import java.io.ObjectInputValidation;
import java.io.Serializable;

public class Employee extends Manager implements Company, Serializable, ObjectInputValidation {
    private static final long serialVersionUID = 456778567857L;
    public String firstName = "First Name";
    public transient static String middleName = "Middle Name";
    public transient final String lastName;
    public transient final String nickName = "Nick Name";
    private int explicitAge = 45;//Will not be read
    PersonalDetails pd = new PersonalDetails(26,'F');//If we make it transient then null pointer exception
    transient static PersonalDetails pdstat = new PersonalDetails(30,'M');

    public Employee(String lastName) {
        this.lastName = lastName;
    }

    @Override
    public void validateObject() throws InvalidObjectException {
        // TODO Auto-generated method stub
        System.err.println("Object Validation In Progress");
        if(this.explicitAge == 45 || this.nickName.equals("Nick Name")) {
            System.err.println("Object Validation Passed");
        }else{
            throw new InvalidObjectException("Object Validation Failed");
        }
    }
}

class Manager {
    public transient String managerName = "Manager Name";//Transient field wont work here as Manager is not implementing Serializable
}

interface Company {
    String companyCEO = "Mr CEO";
    String companyName = "Company Name";
}
class PersonalDetails implements Serializable {
    transient int age = 40;
    char gender = 'F';
    public PersonalDetails(int age, char gender) {
        this.age = age;
        this.gender = gender;
    }
}

Points to be Noted in Employee.java:

  1. serialVersionUID is explicitly defined to prevent InvalidClassException during deserialization, as the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations and can produce different serialVersionUIDs in different environments.

  2. firstName will be serialized, and the default value can be overridden in subsequent classes that are serializing Employee.java

  3. middleName, lastName and nickName are either transient static or transient final. Always remember, transient and static fields are never get serialized. The value which will be restored for these variables will be the value mentioned in the Employee.class at the time of deserialization.

  4. explicitAge is private. It will be serialized as well but can be read only through Reflection API.

  5. PersonalDetails is a class that is implementing a serializable interface. If it won't, then NullPointerException will be thrown at the time of serialization. Its field's value can be overridden in the subsequent classes. Note that the 'age' field is transient.

  6. There is an interface available to validate the object and its data called 'ObjectInputValidation'. And to validate, the validateObject() method needs to be overridden. 

  7. Please note that the parent class 'Manager' is not implementing the Serializable interface. Though it won't throw any exception, as we are not composing or aggregating the parent class object inside the child class Employee.java. So here, the only point we can observe is that the transient keyword won't work here.

  8. 'Company' is an interface, so all its fields are final by default. Please note Interface does not accept the transient keyword for its member variables.

SerializaitonClass.java

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class SerializaitonClass {

    public static void main(String[] args) {
        Employee emp = new Employee("Last Name");
        emp.firstName = "Overriden First Name";
        emp.middleName = "Overriden Middle Name";
        emp.managerName = "Overriden Manager Name";
        emp.pd.age = 28;
        emp.pd.gender = 'M';
        emp.pdstat.age = 35;
        emp.pdstat.gender = 'M';

        try {
            FileOutputStream fileOut = new FileOutputStream("./employee.txt");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(emp);
            out.close();
            fileOut.close();
            System.out.printf("Serialized data is saved in ./employee.txt file");
        } catch (IOException i) {
            i.printStackTrace();
        }
    }
}

DeserializationClass.java

import java.io.*;

public class DeserializationClass{
    public static void main(String[] args) {
        Employee emp = null;
        try {
            FileInputStream fileIn = new FileInputStream("./employee.txt");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            emp = (Employee) in.readObject();
            emp.validateObject();
            in.close();
            fileIn.close();
        } catch (IOException i) {
            i.printStackTrace();
            return;
        } catch (ClassNotFoundException c) {
            System.out.println("Employee class not found");
            c.printStackTrace();
            return;
        } 
        System.out.println("serialVersionUID = "+ObjectStreamClass.lookup(emp.getClass()).getSerialVersionUID());
        System.out.println("Deserializing Employee...");
        System.out.println("First Name of Employee: " + emp.firstName);
        System.out.println("Middle Name of Employee: " + emp.middleName);
        System.out.println("Last Name of Employee: " + emp.lastName);
        System.out.println("Nick Name of Employee: " + emp.nickName);
        System.out.println("Age of Employee: " + emp.pd.age);
        System.out.println("Gender of Employee: " + emp.pd.gender);
        System.out.println("Static Age of Employee: " + emp.pdstat.age);
        System.out.println("Static Gender of Employee: " + emp.pdstat.gender);
        System.out.println("Company Name: "+emp.companyName);
        System.out.println("Company CEO: "+emp.companyCEO);
        System.out.println("Manager Name: "+emp.managerName);
    }
}

Output

Image title

Still thinking about the security of your object? If you want to encrypt and sign the entire object, then go for either the javax.crypto.SealedObject and/or java.security.SignedObject wrappers. Both are serializable and box the original object.

But what happens to the Singleton class when it gets serialized? Oops, it creates the new object! Don't worry! Implement the following method, which can be used to unpack the proxy.

ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;

Still have questions? Help me to help yourselves.

Microservices for Java, explained. Revitalize your legacy systems (and your career) with Reactive Microservices Architecture, a free O'Reilly book. Brought to you in partnership with Lightbend.

Topics:
java ,serialization ,transient keyword in java ,deserialization

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}