My new website on Artificial Intelligence and Machine Learning www.aimlfront.com

Serialization in Java

Java serialization is to write an object into a stream, so that it can be transported through a network. Stream has object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
Most impressive is that the entire process is JVM independent, meaning an object can be serialized on one platform and deserialized on an entirely different platform.
Classes ObjectInputStream and ObjectOutputStream are high-level streams that contain the methods for serializing and deserializing an object.
The ObjectOutputStream class contains many write methods for writing various data types, but one method in particular stands out:
public final void writeObject(Object x) throws IOException
The above method serializes an Object and sends it to the output stream. Similarly, the ObjectInputStream class contains the following method for deserializing an object:
public final Object readObject() throws IOException,
ClassNotFoundException
This method retrieves the next Object out of the stream and deserializes it. The return value is Object, so you will need to cast it to its appropriate data type.

Serilization Example:

Serilizable object:
package com.java.bean;

import java.io.Serializable;

public class SerializationBean implements Serializable {
	
	private static final long serialVersionUID = 1L;
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}
Write an object into stream in file:

package com.java.core;

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

import com.java.bean.SerializationBean;

public class SerializationTest {
	public static void serialize(String outFile, Object serializableObject)
			throws IOException {
		FileOutputStream fos = new FileOutputStream(outFile);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(serializableObject);
	}

	public static void main(String args[]) throws IOException,
			FileNotFoundException, ClassNotFoundException {
		SerializationBean serialB = new SerializationBean();
		serialB.setName("JavaVillage");
		serialize("serial.txt", serialB);
	}

} 
Will try to open serial.txt:

Serialization code in file

Read an object from Stream:
package com.java.core;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

import com.java.bean.SerializationBean;

public class DeSerializationTest {

	public static Object deSerialize(String serilizedObject)
			throws FileNotFoundException, IOException, ClassNotFoundException {
		FileInputStream fis = new FileInputStream(serilizedObject);
		ObjectInputStream ois = new ObjectInputStream(fis);
		return ois.readObject();
	}

	public static void main(String args[]) throws IOException,
			FileNotFoundException, ClassNotFoundException {
		
		SerializationBean sb = (SerializationBean) deSerialize("serial.txt");
		System.out.println("Serialization Object Name value: "+sb.getName());
	}
}
Output: Serialization Object Name value: JavaVillage
Note:
1)If we miss object implements serializable, will get NoSerilizableObjectException. Using implements we can make object persist. That's why while using hibernate will make POJO's Serializable to make object persists across session.
2) Based on update serilizable will get value from deserialization. That means we have two classes(SerializationTest, SerializationTest1 classes)with different name value(JavaVillage, Javavillage1), based on recent (nothing but recent execuetion) serializable object will get value.
Execute SerializationTest, will get Name as Javavillage.
Second try to execute SerializationTest1, this time will get Name as Javavillage1 while executing DeSerializationTest
Because same serializable object will give same value based on recent serializable.

Guidelines for serialVersionUID

* always include it as a field, for example: "private static final long serialVersionUID = 1L; " include this field even in the first version of the class, as a reminder of its importance
* do not change the value of this field in future versions, unless you are knowingly making changes to the class which will render it incompatible with old serialized objects
* new versions of Serializable classes may or may not be able to read old serialized objects; it depends upon the nature of the change; provide a pointer to Sun's guidelines for what constitutes a compatible change, as a convenience to future maintainers.
For this one I want to show you one example for this.
For example for serializable object serialVersionUID=1L, using that object we have write the stream into file. After that we can deserialize and we can get it.
Next we changed that serialVersionUID=3L, made it as 3L something like that. But we forgot to serialize the object that means we forgot run the SerializationTest, directly we are trying to execute Deserialazation(Deserialize an object). So will get
Exception in thread "main" java.io.InvalidClassException: com.java.bean.SerializationBean; 
local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 3

    at java.io.ObjectStreamClass.initNonProxy(Unknown Source)

    at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)

    at java.io.ObjectInputStream.readClassDesc(Unknown Source)

    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)

    at java.io.ObjectInputStream.readObject0(Unknown Source)

    at java.io.ObjectInputStream.readObject(Unknown Source)

    at com.java.core.DeSerializationTest.deSerialize(DeSerializationTest.java:16)

    at com.java.core.DeSerializationTest.main(DeSerializationTest.java:22)
Unless you are knowingly making changes to the class which will render it incompatible with old serialized objects. To avoid this after changing serialVersionUID, we have to serialize the object then we have to deserilize the object. We have to one thing like not recommended to change serialVersionUID frequently.
Serialization and subclassing:
Serializable object subclasses also serializable.
For that see below example:
package com.java.bean;

public class SubClassSerializationBean extends SerializationBean {	
	private static final long serialVersionUID = 6L;
	private int empID;
	public int getEmpID() {
		return empID;
	}
	public void setEmpID(int empID) {
		this.empID = empID;
	}
}
Write a stream using above class which was extending SerializationBean. This bean has implements Serializable.
package com.java.core;

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

import com.java.bean.SubClassSerializationBean;

public class SubClassSerialization {
	public static void serialize(String outFile, Object serializableObject)
			throws IOException {
		FileOutputStream fos = new FileOutputStream(outFile);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(serializableObject);
	}

	public static void main(String args[]) throws IOException,
			FileNotFoundException, ClassNotFoundException {
		SubClassSerializationBean serialB = new SubClassSerializationBean();
		serialB.setName("Subclass");
		serialB.setEmpID(467214);
		serialize("serial.txt", serialB);
	}

}

Deserialize the object
package com.java.core;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

import com.java.bean.SubClassSerializationBean;

public class DeSerializationTest {

	public static Object deSerialize(String serilizedObject)
			throws FileNotFoundException, IOException, ClassNotFoundException {
		FileInputStream fis = new FileInputStream(serilizedObject);
		ObjectInputStream ois = new ObjectInputStream(fis);
		return ois.readObject();
	}

	public static void main(String args[]) throws IOException,
			FileNotFoundException, ClassNotFoundException {
		
		SubClassSerializationBean sb = (SubClassSerializationBean) deSerialize("serial.txt");
		System.out.println("Serialization Object Name value: "+sb.getName());
		System.out.println("Serialization Object EmpID value: "+sb.getEmpID());
	}
}
Expected output from subclass of serializable object:
Serialization Object Name value: Subclass
Serialization Object EmpID value: 467214

Subclasses and Serialization

Only suclassess are serializable if super class is serializable.If subclass is serializable, super class is not serializable. Most abstract classes do not implement Serializable they may still need to allow their subclasses to do so, if desired.