Friday, March 21, 2014

Serialization in JAVA


The primary purpose of Serialization is to convert an object in to a sequence of byte. This stream of data will not only contain the data but also about the object type.This serialized object can be used to transport through a network and then it can be deserialized to build the object again.In order to make a java class serializable Your Java class just needs to implements java.io.Serializable and if a field is not serializable it must be marked transient.Lets try to understand the concept with the use of few example

Serialization

We will use a base code and try to modify it to understand each and every part of it.

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

public class Employee implements java.io.Serializable {
String name;
String designation;
transient String department;
String technology;
//static final long serialVersionUID =1L;



public static void main(String[] args) {
Employee e = new Employee();
e.name = "Arpit Rahi";
e.designation = "Consultant";
e.department = "Oracle";
e.technology = "FMW";
try {
FileOutputStream fileOut =new FileOutputStream("C:\\Users\\arahi\\Desktop\\Temp\\test.txt");
// ObjectOutputStream out = new ObjectOutputStream(fileOut);
// out.writeObject(e);
// out.close();
// fileOut.close();
System.out.printf("Data Serialized");
} catch (IOException i) {
i.printStackTrace();
}
}
}


On execution this will generate a file test.txt in the following location C:\Users\arahi\Desktop\Temp

and it will be empty.

So FileOutputSteam essentially has create a file for you in the location.

Now once the file is create can we not directly write into it--> the answer is no as it doesn't provide methods to write object





As you can observer an object of the class FileOutputStream is used to write binary data to a file in the file-system. That is we need some other method to pass binary data to this which can be achieved through ObjectOutputStream.

An object of the class ObjectOutputStream is used to take an object in Java and convert it to binary to be written to a file output stream or to another binary stream such as to a network socket.

Understanding this we will create an Object of ObjectOutputStream

So the modified code will be


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

public class Employee implements java.io.Serializable {
String name;
String designation;
transient String department;
String technology;
//static final long serialVersionUID =1L;


public static void main(String[] args) {
Employee e = new Employee();
e.name = "Arpit Rahi";
e.designation = "Consultant";
e.department = "Oracle";
e.technology = "FMW";
try {
FileOutputStream fileOut =
new FileOutputStream("C:\\Users\\arahi\\Desktop\\Temp\\test.txt");

ObjectOutputStream out = new ObjectOutputStream(fileOut);
// out.writeObject(e);
// out.close();
// fileOut.close();
System.out.printf("Data Serialized");
} catch (IOException i) {
i.printStackTrace();
}
}
}


On execution this will generate a file test.txt in the following location C:\Users\arahi\Desktop\Temp

and this time it will not be empty it will contain some byte code.
So now we are capable of writing in to the file so lets use a method to pass the object.

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

public class Employee implements java.io.Serializable {
String name;
String designation;
transient String department;
String technology;
//static final long serialVersionUID =1L;


public static void main(String[] args) {
Employee e = new Employee();
e.name = "Arpit Rahi";
e.designation = "Consultant";
e.department = "Oracle";
e.technology = "FMW";
try {
FileOutputStream fileOut =
new FileOutputStream("C:\\Users\\arahi\\Desktop\\Temp\\test.txt");

ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
// out.close();
// fileOut.close();
System.out.printf("Data Serialized");
} catch (IOException i) {
i.printStackTrace();
}
}
}

Ideally this code will do the work but it is a best practice to close the stream whioh you have opened hence just uncomment the two statement


out.close();
fileOut.close();


Now few things to note down there. AS we have discussed earlier if you dont want to serialize an object make it transient. In our code


transient String department; -->department is marked as transient so now if you will go to the test.txt you can find that the code has not written details of department.




This is because the field is marked as transient and we have discussed earlier that if a field is not serializable it must be marked transient.


So we have the full working code now but still there is an issue.


That is how to control the version of object being serialized. That is when you add or modify any field in class then already serialized class will not be able to recover because there is no version control. To solve this purpose there is property that has to be used for version control it is called serialVersionUID.SerialVersionUID is used for version control of object. serialVersionUID generated for new class and for old serialized object will be different.

So we will just change the code to uncomment the serialVersionUID



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

public class Employee implements java.io.Serializable {
String name;
String designation;
transient String department;
String technology;
static final long serialVersionUID =2L;


public static void main(String[] args) {
Employee e = new Employee();
e.name = "Arpit Rahi";
e.designation = "Consultant";
e.department = "Oracle";
e.technology = "FMW";
try {
FileOutputStream fileOut =
new FileOutputStream("C:\\Users\\arahi\\Desktop\\Temp\\test.txt");

ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Data Serialized");
} catch (IOException i) {
i.printStackTrace();
}
}
}

If you will run this code you can see an extra entry in the text file for the serialVersionUID



You will get a “InvalidClassException” when you write a serialization class with serialVersionUID “1L” but try to retrieve it back with updated serialization class, serialVersionUID “2L”.

Next we will try to see how to deserialize the object and capture other details.

No comments: