What is meant by \"object serialization\"? Can you please explain it with some examples?
Java Object Serialization
Serialization is a mechanism to transform a graph of Java objects into an array of bytes for storage(to disk file
) or transmission(across a network
), then by using deserialization we can restore the graph of objects.
Graphs of objects are restored correctly using a reference sharing mechanism. But before storing, check whether serialVersionUID from input-file/network and .class file serialVersionUID are the same. If not, throw a java.io.InvalidClassException
.
Each versioned class must identify the original class version for which it is capable of writing streams and from which it can read. For example, a versioned class must declare:
serialVersionUID Syntax
// ANY-ACCESS-MODIFIER static final long serialVersionUID = (64-bit has)L; private static final long serialVersionUID = 3487495895819393L;
serialVersionUID is essential to the serialization process. But it is optional for the developer to add it into the java source file. If a serialVersionUID is not included, the serialization runtime will generate a serialVersionUID and associate it with the class. The serialized object will contain this serialVersionUID along with other data.
Note - It is strongly recommended that all serializable classes explicitly declare a serialVersionUID, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations
, and can thus result in unexpected serialVersionUID conflicts during deserialization, causing deserialization to fail.
Inspecting Serializable Classes
A Java object is only serializable. if a class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable.
A class must implement java.io.Serializable interface in order to serialize its object successfully. Serializable is a marker interface and used to inform the compiler that the class implementing it has to be added serializable behavior. Here Java Virtual Machine (JVM) is responsible for its automatic serialization.
transient Keyword:
java.io.Serializable interface
While serializing an object, if we don't want certain data members of the object to be serialized we can use the transient modifier. The transient keyword will prevent that data member from being serialized.
- Fields declared as transient or static are ignored by the serialization process.
TRANSIENT & VOLATILE
+--------------+--------+-------------------------------------+ | Flag Name | Value | Interpretation | +--------------+--------+-------------------------------------+ | ACC_VOLATILE | 0x0040 | Declared volatile; cannot be cached.| +--------------+--------+-------------------------------------+ |ACC_TRANSIENT | 0x0080 | Declared transient; not written or | | | | read by a persistent object manager.| +--------------+--------+-------------------------------------+
class Employee implements Serializable {
private static final long serialVersionUID = 2L;
static int id;
int eno;
String name;
transient String password; // Using transient keyword means its not going to be Serialized.
}
Implementing the Externalizable interface allows the object to assume complete control over the contents and format of the object's serialized form. The methods of the Externalizable interface, writeExternal and readExternal, are called to save and restore the objects state. When implemented by a class they can write and read their own state using all of the methods of ObjectOutput and ObjectInput. It is the responsibility of the objects to handle any versioning that occurs.
class Emp implements Externalizable {
int eno;
String name;
transient String password; // No use of transient, we need to take care of write and read.
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(eno);
out.writeUTF(name);
//out.writeUTF(password);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.eno = in.readInt();
this.name = in.readUTF();
//this.password = in.readUTF(); // java.io.EOFException
}
}
Only objects that support the java.io.Serializable or java.io.Externalizable interface can be written to
/read from
streams. The class of each serializable object is encoded including the class name and signature of the class, the values of the object's fields and arrays, and the closure of any other objects referenced from the initial objects.
Serializable Example For Files
public class SerializationDemo {
static String fileName = "D:/serializable_file.ser";
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
Employee emp = new Employee( );
Employee.id = 1; // Can not Serialize Class data.
emp.eno = 77;
emp.name = "Yash";
emp.password = "confidential";
objects_WriteRead(emp, fileName);
Emp e = new Emp( );
e.eno = 77;
e.name = "Yash";
e.password = "confidential";
objects_WriteRead_External(e, fileName);
/*String stubHost = "127.0.0.1";
Integer anyFreePort = 7777;
socketRead(anyFreePort); //Thread1
socketWrite(emp, stubHost, anyFreePort); //Thread2*/
}
public static void objects_WriteRead( Employee obj, String serFilename ) throws IOException{
FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
objectOut.writeObject( obj );
objectOut.close();
fos.close();
System.out.println("Data Stored in to a file");
try {
FileInputStream fis = new FileInputStream( new File( serFilename ) );
ObjectInputStream ois = new ObjectInputStream( fis );
Object readObject;
readObject = ois.readObject();
String calssName = readObject.getClass().getName();
System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException
Employee emp = (Employee) readObject;
System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void objects_WriteRead_External( Emp obj, String serFilename ) throws IOException {
FileOutputStream fos = new FileOutputStream(new File( serFilename ));
ObjectOutputStream objectOut = new ObjectOutputStream( fos );
obj.writeExternal( objectOut );
objectOut.flush();
fos.close();
System.out.println("Data Stored in to a file");
try {
// create a new instance and read the assign the contents from stream.
Emp emp = new Emp();
FileInputStream fis = new FileInputStream(new File( serFilename ));
ObjectInputStream ois = new ObjectInputStream( fis );
emp.readExternal(ois);
System.out.format("Obj[No:%s, Name:%s, Pass:%s]", emp.eno, emp.name, emp.password);
ois.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Serializable Example Over Network
Distributing object's state across different address spaces, either in different processes on the same computer, or even in multiple computers connected via a network, but which work together by sharing data and invoking methods.
/**
* Creates a stream socket and connects it to the specified port number on the named host.
*/
public static void socketWrite(Employee objectToSend, String stubHost, Integer anyFreePort) {
try { // CLIENT - Stub[marshalling]
Socket client = new Socket(stubHost, anyFreePort);
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.writeObject(objectToSend);
out.flush();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Creates a server socket, bound to the specified port.
public static void socketRead( Integer anyFreePort ) {
try { // SERVER - Stub[unmarshalling ]
ServerSocket serverSocket = new ServerSocket( anyFreePort );
System.out.println("Server serves on port and waiting for a client to communicate");
/*System.in.read();
System.in.read();*/
Socket socket = serverSocket.accept();
System.out.println("Client request to communicate on port server accepts it.");
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Employee objectReceived = (Employee) in.readObject();
System.out.println("Server Obj : "+ objectReceived.name );
socket.close();
serverSocket.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
@see
Serialization is the process of saving an object in a storage medium (such as a file, or a memory buffer) or to transmit it over a network connection in binary form. The serialized objects are JVM independent and can be re-serialized by any JVM. In this case the "in memory" java objects state are converted into a byte stream. This type of the file can not be understood by the user. It is a special types of object i.e. reused by the JVM (Java Virtual Machine). This process of serializing an object is also called deflating or marshalling an object.
The object to be serialized must implement java.io.Serializable
Interface.
Default serialization mechanism for an object writes the class of the object, the class signature, and the values of all non-transient and non-static fields.
class ObjectOutputStream extends java.io.OutputStream implements ObjectOutput,
ObjectOutput
interface extends the DataOutput
interface and adds methods for serializing objects and writing bytes to the file. The ObjectOutputStream
extends java.io.OutputStream
and implements ObjectOutput
interface. It serializes objects, arrays, and other values to a stream. Thus the constructor of ObjectOutputStream
is written as:
ObjectOutput ObjOut = new ObjectOutputStream(new FileOutputStream(f));
Above code has been used to create the instance of the ObjectOutput
class with the ObjectOutputStream( )
constructor which takes the instance of the FileOuputStream
as a parameter.
The ObjectOutput
interface is used by implementing the ObjectOutputStream
class. The ObjectOutputStream
is constructed to serialize the object.
Deserializing an Object in java
The opposite operation of the serialization is called deserialization i.e. to extract the data from a series of bytes is s known as deserialization which is also called inflating or unmarshalling.
ObjectInputStream
extends java.io.InputStream
and implements ObjectInput
interface. It deserializes objects, arrays, and other values from an input stream. Thus the constructor of ObjectInputStream
is written as:
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(f));
Above code of the program creates the instance of the ObjectInputStream
class to deserialize that file which had been serialized by the ObjectInputStream
class. The above code creates the instance using the instance of the FileInputStream
class which holds the specified file object which has to be deserialized because the ObjectInputStream()
constructor needs the input stream.
I liked the way @OscarRyz presents. Although here i am continuing the story of serialization which was originally written by @amitgupta.
Even though knowing about the robot class structure and having serialized data Earth's scientist were not able to deserialize the data which can make robots working.
Exception in thread "main" java.io.InvalidClassException:
SerializeMe; local class incompatible: stream classdesc
:
Mars's scientists were waiting for the complete payment. Once the payment was done Mars's scientists shared the serialversionUID with Earth's scientists. Earth's scientist set it to robot class and everything became fine.
Return the file as an Object : http://www.tutorialspoint.com/java/java_serialization.htm
import java.io.*;
public class SerializeDemo
{
public static void main(String [] args)
{
Employee e = new Employee();
e.name = "Reyan Ali";
e.address = "Phokka Kuan, Ambehta Peer";
e.SSN = 11122333;
e.number = 101;
try
{
FileOutputStream fileOut =
new FileOutputStream("/tmp/employee.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in /tmp/employee.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
import java.io.*;
public class DeserializeDemo
{
public static void main(String [] args)
{
Employee e = null;
try
{
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
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("Deserialized Employee...");
System.out.println("Name: " + e.name);
System.out.println("Address: " + e.address);
System.out.println("SSN: " + e.SSN);
System.out.println("Number: " + e.number);
}
}
|*| Serializing a class : Converting an object to bytes and bytes back to object (Deserialization).
class NamCls implements Serializable
{
int NumVar;
String NamVar;
}
|=> Object-Serialization is process of converting the state of an object into steam of bytes.
|=> Object-Deserialization is the process of getting the state of an object and store it into an object(java.lang.Object).
|=> A Java object is only serializable, if its class or any of its superclasses
|=> Static fields in a class cannot be serialized.
class NamCls implements Serializable
{
int NumVar;
static String NamVar = "I won't be serializable";;
}
|=> If you do not want to serialise a variable of a class use transient keyword
class NamCls implements Serializable
{
int NumVar;
transient String NamVar;
}
|=> If a class implements serializable then all its sub classes will also be serializable.
|=> If a class has a reference of another class, all the references must be Serializable otherwise serialization process will not be performed. In such case,
NotSerializableException is thrown at runtime.
Serialization means persisting objects in java. If you want to save the state of the object and want to rebuild the state later (may be in another JVM) serialization can be used.
Note that the properties of an object is only going to be saved. If you want to resurrect the object again you should have the class file, because the member variables only will be stored and not the member functions.
eg:
ObjectInputStream oos = new ObjectInputStream(
new FileInputStream( new File("o.ser")) ) ;
SerializationSample SS = (SearializationSample) oos.readObject();
The Searializable is a marker interface which marks that your class is serializable. Marker interface means that it is just an empty interface and using that interface will notify the JVM that this class can be made serializable.