1. What is Serialization?
Serialization is the process of converting an object and its states to a binary stream that can then be saved into a database, cached or sent over the network to another JVM.
2. What is Deserialization?
Deserialization is the process of converting back a serialized object.
import java.io.Serializable; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; public class User implements Serializable { private static final long serialVersionUID = 3L; private String name; private int age; private String email; transient private double height; //setters and getters @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } }
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SerializationDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { String path = "serialized_user.ser"; User serializedUser = serialize(path); System.out.println("serializedUser=" + serializedUser.toString()); User deserializedUser = deserialize(path); System.out.println("deserializedUser=" + deserializedUser.toString()); } private static User serialize(String path) throws IOException { FileOutputStream fileStream = new FileOutputStream(path); ObjectOutputStream objectStream = new ObjectOutputStream(fileStream); User user = new User(); user.setAge(21); user.setName("Laulau"); user.setEmail("folaukaveinga@gmail.com"); user.setHeight(6.3); objectStream.writeObject(user); objectStream.close(); fileStream.close(); return user; } private static User deserialize(String path) throws IOException, ClassNotFoundException { FileInputStream fileInputStream = new FileInputStream(path); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); User user = (User) objectInputStream.readObject(); objectInputStream.close(); fileInputStream.close(); return user; } }
Result
serializedUser=User[name=Laulau,age=21,email=folaukaveinga@gmail.com] deserializedUser=User[name=Laulau,age=21,email=folaukaveinga@gmail.com]
3. What is Externalization?
Serialization is not very efficient. If you serialize bloated objects having a lot of attributes and properties, you do not wish to serialize. This is where Externalization in Java comes into the picture. Externalization is an advanced way of serialization. It is whenever you need to customize the serialization mechanism.
The class you want to be externalized must implement the Externalizable interface, then serialization of the object will be done using the method writeExternal(). When the Externalizable object is reconstructed at the receiver’s end, an instance will be created using no-argument constructor and this method is called readExternal().
This basically serves the purpose of custom Serialization, where you can decide what to store in a stream.
When to use Externalization?
When you want or need to serialize only part of an object, Externalization is the best option.
How to use Externalization?
By implementing the Externalizable interface, you control the process of reading and writing the objects during serialization and de-serialization process, you need to have the object’s class implemented the interface java.io.Externalizable. Only then you can implement your own code to read and write the object’s states. The methods, readExternal() and writeExternal() are defined by the Externalizable interface.
import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; public class Member implements Externalizable { public static final long serialVersionUID = 2L; private String name; private int age; private String email; transient private double height; // setters and getters @Override public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } @Override public void writeExternal(ObjectOutput out) throws IOException { System.out.println("writing object state..."); // TODO Auto-generated method stub out.writeObject(name); out.writeObject(email); out.writeInt(age); out.writeDouble(height); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { System.out.println("reading object state..."); this.name = (String) in.readObject(); this.email = (String) in.readObject(); this.age = in.readInt(); this.height = in.readDouble(); } }
public class ExternalizeDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { String path = "externalized_member.ser"; Member externalizedMember = serialize(path); System.out.println("externalizedMember=" + externalizedMember.toString()); Member dexternalizedMember = deserialize(path); System.out.println("dexternalizedMember=" + dexternalizedMember.toString()); } private static Member serialize(String path) throws IOException { FileOutputStream fileStream = new FileOutputStream(path); ObjectOutputStream objectStream = new ObjectOutputStream(fileStream); Member member = new Member(); member.setAge(21); member.setName("Laulau"); member.setEmail("folaukaveinga@gmail.com"); member.setHeight(6.3); System.out.println(member.toString()); objectStream.writeObject(member); objectStream.close(); fileStream.close(); return member; } private static Member deserialize(String path) throws IOException, ClassNotFoundException { FileInputStream fileInputStream = new FileInputStream(path); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); Member member = (Member) objectInputStream.readObject(); objectInputStream.close(); fileInputStream.close(); return member; } }
Result
Member[name=Laulau,age=21,email=folaukaveinga@gmail.com] writing object state... externalizedMember=Member[name=Laulau,age=21,email=folaukaveinga@gmail.com] reading object state... dexternalizedMember=Member[name=Laulau,age=21,email=folaukaveinga@gmail.com]
4. What are the differences between Serialization and Externalization?
Externalizable provides us with writeExternal()
and readExternal()
methods that give us control on what attributes and values to serialize. Correct implementation of the Externalizable interface can improve the performance of application drastically.
Externalization | Serialization | |
UID | No need to have it but for best practice you must have it | Needs a serialVersionUID |
Storage | Store the data per attribute. | Store the whole object directly. |
Access | Provides complete control to the serialization and deserialization process. | No access |
5. How many methods does Serializable have?
Zero. Serializable is a marker interface.
6. What is a serialVersionUID? What happens when you don’t explicitly provide?
serialVersionUID is a version control id. It is basically the hashcode of the object. So if you change the object(add or remove an attribute) then the hashcode will be different so an already serialized object will not be able to deserialize. Java serialization process relies on correct serialVersionUID for recovering the state of the serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch
When an object is serialized, the serialVersionUID is serialized along with the other contents. Later when that is deserialized, the serialVersionUID from the deserialized object is extracted and compared with the serialVersionUID of the loaded class. If the numbers do not match then, InvalidClassException is thrown.
serialVersionUID is a 64-bit hash of the class name, interface class names, methods and fields. Serialization runtime generates a serialVersionUID if you do not add one. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations and can produce different serialVersionUID in different environments.
If you don’t provide it, Java will provide it for you.
7. What happens if an object is serializable but it includes a reference to a non-serializable object?
Java will throw a NotSerializableException. To fix this issue you can do either one of these two things:
a. Make the non-serializable object serializable by making its class implement the Serializable interface.
b. Make the non-serializable object transient or static.
8. If a class is serializable but its superclass in not, what will be the state of the instance variables inherited from super class after deserialization?
The state will be its default value. For example:
int age; -> age = 0;
String name; -> name = null;
9. To serialize an array or a collection all the members of it must be serializable. True /False?
true
All standard implementations of collections List, Set and Map interface already implement java.io.Serializable. This means you do not really need to write anything specific to serialize collection objects. However, you should keep the following things in mind before you serialize a collection object – Make sure all the objects added in a collection are Serializable.
10. While serializing you want some of the members not to serialize, how do you achieve it?
If you don’t want any field to be part of the object’s state then declare it either static or transient based on your need and it will not be included during the serialization process.
Variables marked with transient are not included in the process of serialization and are not part of the object’s serialized state.
The static variables belong to a class are not part of the state of the object so they are not saved as part of the serialized object.
Why static variables are not serialized in Java?
The Java variables declared as static are not considered part of the state of an object since they are shared by all instances of that class. Saving static variables with each serialized object would have following problems
11. What should you take care of when serializing an object?
You should make sure that all the included objects are also serializable. If any of the objects is not serializable then it throws a NotSerializableException.
12. Suppose a superclass of a new class implements Serializable interface, how can you avoid new class to being serialized?
Use Externalization and exclude the new class from the serialization process.
13. What are the ways to speed up Object Serialization? How to improve Serialization performance?
The default Java Serialization mechanism is really useful, however it can have a really bad performance based on your application and business requirements. The serialization process performance heavily depends on the number and size of attributes you are going to serialize for an object. Below are some tips you can use for speeding up the marshaling and un-marshaling of objects during Java serialization process.
14. Do constructors get invoked or run at deserialization?
When an instance of a serializable class is deserialized, the constructor does not run. If constructors were invoked it will give back the initial values rather than the value they had at the time of serialization.
15. What are the compatible and incompatible changes when dealing with versioned serialized objects during serialization?
Changes to a serializable class can be compatible or incompatible. Following is the list of changes which are compatible:
List of incompatible changes:
16. What are the guidelines for using serialVersionUID?
17. Does setting the serialVersionUID class field improve Java serialization performance?
Declaring an explicit serialVersionUID field in your classes saves some CPU time only the first time the JVM process serializes a given Class. However the gain is not significant, In case when you have not declared the serialVersionUID its value is computed by JVM once and subsequently kept in a soft cache for future use.
18. Suppose you have a class in which you serialized and stored in persistence and later modified that class to add a new field. What will happen if you deserialize the object already serialized?
It depends on whether a class has its own serialVersionUID or not. As we know that if we don’t provide serialVersionUID in our code java compiler will generate it and normally it’s equal to hashCode of the object. By adding any new field there is a chance that new serialVersionUID generated for that class version is not the same as the serialized object. In this case, Java Serialization API will throw java.io.InvalidClassException
and this is the reason its recommended to have your own serialVersionUID in code and make sure to keep it same always for a single class.