Serialization and Deserialization in Java

For Java 11 Certification Exam Practice Questions, refer http://talks.skilltoz.com/java-11-certification-exam-questions/

What is Serialization and deserialization?

Serialization is the process of converting an object into a byte stream. The opposite process of restoring an object from the byte stream, is known as deserialization.

What is the significance of the Serializable interface?

An object can be serialized only if the object’s class implements java.io.Serializable interface. This is a marker interface ie; it has no methods.

public class Student implements Serializable {
	private String name;
    int age;
}

In the above example, the class Student implements Serializable interface, so it’s objects can be serialized.

How do you serialize an object?

We can serialize an object, by invoking the following method of ObjectOutputStream.

public void writeObject(Object obj) throws IOException

Let us create an object of the class Student and try to serialize it.

Student student = new Student();
student.setAge(10);
student.setName("Tina");

To serialize the student object to a file “myfile.txt”, we need to use FileOutputStream and wrap it using ObjectOutputStream as shown.

FileOutputStream fileOutputStream = new FileOutputStream("myfile.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(student);
objectOutputStream.flush();
objectOutputStream.close();

The above code causes the Student object (with name as “Tina” and age as 10) to be serialized into the file “myfile.txt”.

How do you deserialize an object?

We can deserialize an object, by invoking the following method of ObjectInputStream.

public Object readObject() throws IOException, ClassNotFoundException

Let us see how we can deserialize the Student object from a byte stream. We read from the file using FileInputStream and wrap it using ObjectInputStream as shown above.

FileInputStream fileInputStream = new FileInputStream("myfile.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
Student student = (Student) objectInputStream.readObject();
objectInputStream.close();
System.out.println(student.getName());
System.out.println(student.getAge());

Here, the name is printed as “Tina” and age as 10.

What happens when certain fields of a serializable object are marked transient?

We can prevent serialization of any particular instance variable in an object by marking it as transient.

Consider a class User below.

public class User implements Serializable {
	private String name;
    private transient char[] password;
}

When this class is serialized, password field will not be written to the stream as it is marked as transient.

What will be the value of a transient field when the object is deserialized?

When an object is deserialized, the transient fields are initialized to their default Java values, such as null for objects, 0 for int, 0.0 for double and so on.

Will the constructors of an object’s class be called when an object of a class is deserialized?

When you deserialize an object, the constructor of the serialized class or instance initializers are not called during object creation. However, the default constructor of the first nonserializable parent class in the class hierarchy will be invoked.

What will be the value of a static field when the object is deserialized?

Static variables are ignored when the object is deserialized. As they are class level data, static fields retain the value that was set to them last.

How do you ensure that the objects of a class can be serialized?

The following conditions should be met to ensure that the objects of a class can be serialized.

  1. The class of the object must implement Serializable directly or indirectly.
  2. Every instance variable of the class has to be serializable, marked transient, or has a null value at the time of serialization.

Is it possible to specify which fields are to be serialized?

Default serializable fields of a class are defined to be the non-transient and non-static fields. We already saw that a particular field can be prevented from being serialized by marking it as transient.

Another way to override the default serializable behavior is by declaring a special field in the Serializable class, serialPersistentFields. This field must be initialized with an array of ObjectStreamField objects that list the names and types of the serializable fields. The modifiers for the field are required to be private, static, and final.

What will happen if both transient and serialPersistentFields are declared in a class?

If correctly declared, serialPersistentFields takes precedence over transient. Let us modify the Student class to use serialPersistentFields as well as transient.

public class Student implements Serializable {
	private String name;
	private transient Integer age;
	private static final ObjectStreamField[] serialPersistentFields = { 
            new ObjectStreamField("name", String.class), 
			new ObjectStreamField("age", Integer.class) 
     };
}

What will happen if you serialize an object of the above class? Both name and age will be part of the serialized data, even though age is declared transient. This is because serialPersistentFields definition is considered and transient is ignored.

Quiz

For practice test/quiz questions on the topic of serialization, please refer http://talks.skilltoz.com/quiz-serialization-and-deserialization-in-java/

References

https://docs.oracle.com/javase/8/docs/technotes/guides/serialization/index.html

https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html

https://docs.oracle.com/javase/7/docs/platform/serialization/spec/serial-arch.html

Leave a Reply

Your email address will not be published. Required fields are marked *