Saturday 3 August 2013

44:Serialization

Learning Objectives
After completing this session, you will be able to:
‰  Define Serialization
‰  Identify what is preserved when an object is serialized
‰  Write Transient keyword
‰  Describe the process of serialization
‰  Explain the process of deserialization
‰  Define Version control
‰  Change the default protocol
‰  Create your own protocol by Externalizable interface
Serialization
Serialization is an ability to read or write an object to a stream. It is the process of "flattening" an
object.
Serialization is used to save object to some permanent storage. Its state should be written in a
serialized form to a file such that the object can be reconstructed at a later time from that file.
Serialization is used to pass on to another object bythe OutputStream class and can be sent over
the network.
Streams Used for Serialization
The streams used for serialization are:
‰  ObjectOutputStream:For serializing (flattening an object)
‰  ObjectInputStream:For deserializing (reconstructing an object)
Requirement for Serialization
‰  Serialization is required to allow an object to be serializable:
‰  Its class should implement the Serializable interface:
oSerializable interface is marker interface
oIts class should also provide a default constructor (a constructor with no
arguments)
‰  Serializability is inherited:
oDo not have to implement Serializable on every class
oCan just implement Serializable once along the class hierarchy
Non-Serializable Objects
‰  Most Java classes are serializable.
‰  Objects of some system-level classes are not serializable:
‰  Because the data that they represent, changes constantly:
‰  Reconstructed object will contain different value anyway
‰  For example, thread running in your JVM would be applying the memory of your
system. Persisting it and trying to run it inyour JVM would make no sense at all.
‰  A NotSerializableException is thrown if you try to serialize non-serializable objects
What is Preserved when an Object is Serialized?
When an object is serialized enough information ispreserved that is needed to reconstruct the
object instance at a later time:
‰  Only the data of the object is preserved
‰  Methods and constructors are not part of the serialized stream
‰  Class information is included
The transient Keyword
‰  The transient modifier applies only to instance variables.
‰  If you mark an instance variable as transient, you’re telling the JVM to skip (ignore)
this variable when you attempt to serialize the object containing it.
‰  In other words, the transient keyword prevents the data from being serialized.
‰  All fields that are not transient are considered part of the persistent state of an object
and are eligible for persistence.
Example: transient Keyword
1 class MyClass implements Serializable {
2
3 // Skip serialization of the transient field
4 transient Thread thread;
5 transient String fieldIdontwantSerialization;
6
7 // Serialize the rest of the fields
8 int data;
9 String x;
10
11 // More code
12 }
Serialization: Writing an Object Stream
To write an object stream use its writeObject method of the ObjectOutputStream class.
public final void writeObject(Object obj) throws IOException
where obj is the object to be written to the stream
1 import java.io.*;
2 public class SerializeBoolean {
3 SerializeBoolean() {
4 Boolean booleanData = new Boolean("true");
5 try {
6 FileOutputStream fos = new
7 FileOutputStream("boolean.ser");
8 ObjectOutputStream oos = new
9 ObjectOutputStream(fos);
10 oos.writeObject(booleanData);
11 oos.close();
12
13 } catch (IOException ie) {
14 ie.printStackTrace();
15 }
16 }
17
18 public static void main(String args[]) {
19 SerializeBoolean sb = new SerializeBoolean();
20 }
21 }
Deserialization: Reading an Object Stream
To read an object stream use its readObjectmethod of the ObjectInputStream class.
public final Object readObject()
throws IOException, ClassNotFoundException
where obj is the object to be read from the stream
The Object type returned should be typecasted to the appropriate class name before methods on
that class can be executed.
1 import java.io.*;
2 public class UnserializeBoolean {
3 UnserializeBoolean() {
4 Boolean booleanData = null;
5 try {
6 FileInputStream fis = new
7 FileInputStream("boolean.ser");
8 ObjectInputStream ois = new
9 ObjectInputStream(fis);
10 booleanData = (Boolean) ois.readObject();
11 ois.close();
12
13 } catch (Exception e) {
14 e.printStackTrace();
15 }
16 System.out.println("Unserialized Boolean from "
17 + "boolean.ser");
18 System.out.println("Boolean data: " +
19 booleanData);
20 System.out.println("Compare data with true: " +
21 booleanData.equals(new Boolean("true")));
22 }
23
24 public static void main(String args[]) {
25 UnserializeBoolean usb =
26 new UnserializeBoolean();
27 }
28 }
Version Control: Problem Scenario
‰  Imagine that you create a class, instantiateit, and write it out to an object stream.
‰  The flattened object sits in the file system for some time.
‰  Meanwhile, you update the class file, perhaps adding a new field.
‰  What happens when you try to read in the flattened object?
‰  An exception will be thrown specifically, the java.io.InvalidClassException.
Unique Identifier
Why exception is thrown?
‰  Because all classes that are capable ofpersistence have a unique identifier
automatically
‰  If the identifier of the class does not equal the identifier of the flattened object, then the
exception will be thrown
However, if you really think about it, why should it be thrown just because I added a field? Could
not the field just be set to its default value and then written out next time?
Yes, but it takes a little code manipulation. The identifier that is part of all classes is maintained in
a field called serialVersionUID.
If you wish to control versioning, then you simply have to provide the serialVersionUID field
manually and ensure that it is always the same, no matter what changes you make to the class
file.
How do you Generate a Unique ID?
serialver utility is used to generate a unique ID
Example:
serialver MyClass
MyClass static final long serialVersionUID = 10275539472837495L;
Provide your own implementation for readObject() and writeObject() methods
Classes that require special handling during the serialization and deserialization process must
implement special methods with these exact signatures:
‰  private void writeObject(java.io.ObjectOutputStream out)
throws IOException;
‰  private void readObject(java.io.ObjectInputStream in) throws
IOException, ClassNotFoundException;
Provide your own implementation for readObject() and writeObject() methods
The most common reason to implement writeObject() and readObject() is when you have to save
some part of an object’s state manually. If you choose, you can write and read ALL of the state
yourself, but that’s very rare.
When you want to do only a part of the serialization/deserialization yourself, you MUST invoke the
defaultReadObject() and defaultWriteObject() methods to do the rest.
Externalizable Interface
The writeExternal and readExternal methods ofthe Externalizable interface can be implemented
by a class to give the class complete control over the format and contents of the stream for an
object and its super types.
These methods must explicitly coordinate with the super type to save its state.
These methods supersede customized implementations of writeObject() and readObject()
methods.
How does Object Serialization Scheme works with Externalizable
Object Serialization applies the Serializable and Externalizable interfaces
Each object to be stored is tested for the Externalizable interface:
‰  If the object supports Externalizable, thenthe writeExternal() method is called.
‰  If the object does not support Externalizable and does implement Serializable, then
the object is saved using ObjectOutputStream.
Tips and Tricks:
1.Why will you ever write a class that was notserializable?
2.What happens if two objects in the object graph are the same object? Does this object get
saved twice during serialization?
Solution:
1.There are very few reasons, but you might for example, have a security issue where you
do not have a password object stored or you might have an object that makes no sense to
save, because its key instance variables are themselves not serializable, so there is no
useful way for you to make your class serializable.
2.Serialization is smart enough to know when two objects in the graph are the same. In that
case, only one of the objects is saved, and during deserialization, any references to that
single object are restored.
Summary
‰  A class must implement the Serializable interface before its objects can be serialized.
‰  If you mark an instance variable transient, it will not be serialized even though the rest
of the object’s state will be.
‰  If a superclass implements Serializable, then its subclasses do automatically.
‰  If a superclass doesn’t implement Serializable, then when a subclass object is
deserialized, the superclass constructor will run.
Test Your Understanding
1.What is object serialization?
2.What useful purpose does serializationserve?

No comments:

Post a Comment