To Serialize an object means, to convert its state to a byte stream (which can be moved over a network, persisted on a file drive, persisted in a Data base) so that the byte stream can be reverted back into a copy of the object. A Java object is Serializable if its class or any of its superclasses implements the Serializable interface or its subinterface i.e. the Externalizable.
Classes that do not
implement this interface will not have any of their state serialized or
deserialized. All subtypes of a serializable class are themselves serializable.
The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.The default serialization mechanism for an object writes
- the class of the object
- the class signature
- the values of all non-transient and non-static fields - this includes references to other objects (except in transient or static fields) to be written also (only if they are implementing Serializable interface or its subinterface)
Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.
Deserialization is the process of converting the serialized form of an object back into a copy of the object.
What if a class implements Serializable but it's parent class does not?
- To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.
- During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.
NOTE: When traversing a graph, an object may be encountered that does
not support the Serializable interface. In this case the
NotSerializableException will be thrown and will identify the class of the
non-serializable object.
When an object is serialized, information
that identifies its class is recorded in the serialized stream. However, the
class's definition ("class file") itself is not recorded. It is the
responsibility of the system that is deserializing the object to determine how
to locate and load the necessary class files.
What if I want don't want Java to handle Serialization?
The Java platform specifies a default way by
which serializable objects are serialized. A (Java) class can override this
default serialization and define its own way of serializing objects of that
class. The Object Serialization Specification describes object serialization in detail.
Classes that require special handling during the serialization
and deserialization process must implement special methods with these exact
signatures:
- private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {}
- private void writeObject(java.io.ObjectOutputStream stream) throws IOException {}
- private void readObjectNoData() throws ObjectStreamException {}
DataOutput Interface
The
DataOutput
interface provides for converting data
from any of the Java primitive types to a series of bytes and writing these
bytes to a binary stream. There is also a facility for converting a String
into modified UTF-8 format and writing the resulting series of
bytes.
For all the methods in this interface that write bytes, it is
generally true that if a byte cannot be written for any reason, an
IOException
is thrown.There is something known as serialVersionUID; What is it? When to use it? How to use it?
The
serialization runtime associates with each serializable class a version number,
called a serialVersionUID, which is
used during deserialization to verify that the sender and receiver of a
serialized object have loaded classes for that object that are compatible with
respect to serialization. If the receiver has loaded a class for the object
that has a different serialVersionUID than that of the corresponding sender's
class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID
explicitly by declaring a field named "serialVersionUID" that
must be static, final, and of type long:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a
serialVersionUID, then the serialization runtime will calculate a default
serialVersionUID value for that class based on various aspects of the class, as
described in the Java(TM) Object Serialization Specification. However, it
is strongly recommended that all serializable classes
explicitly declare serialVersionUID values, since the default serialVersionUID
computation is highly sensitive to class details that may vary depending on
compiler implementations, and can thus result in
unexpected InvalidClassExceptions during deserialization. Therefore, to
guarantee a consistent serialVersionUID value across different java compiler
implementations, a serializable class must declare an explicit serialVersionUID
value. It is also strongly advised that explicit serialVersionUID declarations
use the private modifier where possible, since such declarations apply
only to the immediately declaring class--serialVersionUID fields are not useful
as inherited members. Array classes cannot declare an explicit
serialVersionUID, so they always have the default computed value, but the
requirement for matching serialVersionUID values is waived for array classes.
Examples demonstrating all the concepts of Serialization have been commited the below githib repo
https://github.com/omerhashmininjago/java-programs/tree/master/src/main/java/com/demonstrate/concepts/serialization
No comments:
Post a Comment