ALL ABOUT SERIALIZABLE
Serialization is a mechanism of converting the state of an object into a byte stream.
Deserialization is the reverse process where the byte stream is used to
recreate the actual Java object in memory. This mechanism is used to persist
the object.
The byte stream created is platform independent. So, the object
serialized on one platform can be deserialized on a different platform.
Serializable is a marker interface.
When an object has to be transferred over a network ( typically through rmi or
EJB) or to persist the state of an object to a file, the object Class needs to
implement Serializable interface. Implementing this interface will allow the
object converted into bytestream and transfer over a network.
Which class compute serialVersionUID
and Serialization mechanism ?
Everytime an object
is serialized the java serialization mechanism automatically computes a hash
value. ObjectStreamClass's computeSerialVersionUID() method
passes the class name, sorted member names, modifiers, and interfaces to the
secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is
also called suid.
So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.
Below two important methods helps in serializing
and deserializing object.
ObjectOutputStream.writeObject()
// serialize and write to the stream
ObjectInputStream.readObject()
// read and deserialize to the stream
public class SerializeObject implements Serializable{
private static final long serialVersionUID = 1L;
int a;
// static
variable won't affect value of serialized object
static String b;
String c;
public static void main(String[] args) throws IOException
{
SerializeObject serialObject = new SerializeObject();
FileOutputStream fo = new FileOutputStream("testSer.ser");
ObjectOutputStream os=new ObjectOutputStream(fo);
os.writeObject(serialObject);
serialObject = new SerializeObject();
FileInputStream fi=new FileInputStream("testSer.ser");
ObjectInputStream oi=new ObjectInputStream(fi);
serialObject =(SerializeObject)
oi.readObject();
System.out.println(serialObject);
oi.close();
}
}
If serialVersionUID is different while writing and reading,
then it’ll throw below exception
Exception
in thread "main" java.io.InvalidClassException: com.javaetutorials.SerializeObject; local class
incompatible: stream classdesc serialVersionUID = 1, local class
serialVersionUID = 2
Object Graph
In Java
it wouldn't make any sense to save the actual value of a reference variable,
because the value of a Java reference has meaning only within the context of a
single instance of a JVM. In other words, if you tried to restore the object in
another instance of the JVM, even running on the same computer on which the
object was originally serialized, the reference would be useless.
If you serialize
a Dog object, the Collar will be serialized automatically.
And if
the Collar class contained a reference to another object, THAT object would also be serialized, and so
on.
Note : Fortunately, the Java serialization mechanism takes care of all of this. When you serialize an object, Java serialization takes care of saving that object's entire "object graph."
That means a deep copy of everything the saved object needs to be restored.
Note : Fortunately, the Java serialization mechanism takes care of all of this. When you serialize an object, Java serialization takes care of saving that object's entire "object graph."
That means a deep copy of everything the saved object needs to be restored.
public class ObjectGraph {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Collar c = new Collar(3);
Dog d = new Dog(c, 8);
FileOutputStream fos = new FileOutputStream("testSerDog.ser");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(d);
os.close();
System.out.println("After Serialization ,b is "+ d.b+" before: collar size is "+ d.getCollar().getCollarSize());
FileInputStream fis = new FileInputStream("testSerDog.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
d = (Dog) ois.readObject();
ois.close();
System.out.println("After deserializtion b value is "+ d.b);
System.out.println("after: collar size is "+
d.getCollar().getCollarSize());
}
}
/*To save Dog
and restore, Collar should also need to be save...
Without making Collar as Serializable
, it throws java.io.NotSerializableException: com.javaetutorials.Collar*/
class Dog implements Serializable {
private static final long serialVersionUID = -8165365370689001304L;
/* >If Collar
is transient and when the Dog is deserialized, it comes back with a null Collar.
Thus it'll throw NullPointerException...To prevent
it, make Collar as static and it'll work...
>If Collar is static , then it'll act as class variable ,
so need to make Collar class serializable and it doesn't participate in Serialization...
*/
>If Collar is static , then it'll act as class variable ,
so need to make Collar class serializable and it doesn't participate in Serialization...
*/
private transient Collar theCollar;
private int dogSize;
// if b
variable is transient i.e its state is not saved ,when deserialize it'll
come back as default value...
public transient int b=10;
public Dog(Collar collar, int size) {
theCollar = collar;
dogSize = size;
}
public Collar getCollar() {
return theCollar;
}
}
/*Collar
must be serializable as it has reference in Dog Object...
To prevent Collar to be serialized, use
Transient keyword...
*/
class Collar implements Serializable {
private static final long serialVersionUID = -8706017246615683290L;
private int collarSize;
public Collar(int size) {
collarSize = size;
}
public int getCollarSize() {
return collarSize;
}
}
Output :
After Serialization ,b is 10 before: collar size is 3
After deserializtion b value is 0
Exception in thread "main" java.lang.NullPointerException
at
com.javaetutorials.ObjectGraph.main(ObjectGraph.java:28)
To prevent NullPointerException, make Collar
as static variable
Output :
After Serialization ,b is 10 before: collar size is 3
After deserializtion b value is 0
after: collar size is 3
Another way to serialize objects :
·
Externalization
implements Serialization
·
XML
Serialization
·
Write an object's content
directly via either the ObjectOutputStream or the DataOutputStream.
What happens if an object is serializable but it
includes a reference to a non-serializable object?
Exception in thread "main" java.io.NotSerializableException: com.javaetutorials.Collar
InvalidClassException - When suid is different during writing and reading of a stream.
ReplyDeleteNotSerializableException- When object is serializable but it includes a reference to a non-serializable object.
NullPointerException- When reference is transient and tried to deserialize