All your distributed objects such as your key and value objects, objects you offer into
distributed queue and your distributed callable/runnable objects have to
beSerializable
.
Hazelcast serializes all your objects into an instance
ofcom.hazelcast.nio.serialization.Data
.
Data
is the binary
representation of an object.
When Hazelcast serializes an object intoData
,
it first checks whether the object is an instance of
com.hazelcast.nio.serialization.DataSerializable
, if not it checks if it is an instance of
com.hazelcast.nio.serialization.Portable
and serializes it accordingly.
For the following types Hazelcast optimizes the serialization a user can not override this behaviour.
Byte
,
Boolean
,
Character
,
Short
,
Integer
,
Long
,
Float
,
Double
,
byte[]
,
char[]
,
short[]
,
int[]
,
long[]
,
float[]
,
double[]
,
String
,
Hazelcast also optimizes the following types, however you can override them by creating a custom serializer
and registering it.
See
Custom Serialization
for more information.
Not that if the object is not instance of any explicit type, Hazelcast uses Java Serialization for Serializable and Externalizable objects. The default behaviour can be changed using a Custom Serialization.
For a faster serialization of objects, Hazelcast recommends to implement
com.hazelcast.nio.serialization.IdentifiedDataSerializable
which is slightly better
version of
com.hazelcast.nio.serialization.DataSerializable
.
Here is an example of a class implementing
com.hazelcast.nio.serialization.DataSerializable
interface.
public class Address implements com.hazelcast.nio.serialization.DataSerializable { private String street; private int zipCode; private String city; private String state; public Address() {} //getters setters.. public void writeData(ObjectDataOutput out) throws IOException { out.writeUTF(street); out.writeInt(zipCode); out.writeUTF(city); out.writeUTF(state); } public void readData(ObjectDataInput in) throws IOException { street = in.readUTF(); zipCode = in.readInt(); city = in.readUTF(); state = in.readUTF(); } }
Lets take a look at another example which is encapsulating a
DataSerializable
field.
public class Employee implements com.hazelcast.nio.serialization.DataSerializable { private String firstName; private String lastName; private int age; private double salary; private Address address; //address itself is DataSerializable public Employee() {} //getters setters.. public void writeData(ObjectDataOutput out) throws IOException { out.writeUTF(firstName); out.writeUTF(lastName); out.writeInt(age); out.writeDouble (salary); address.writeData (out); } public void readData (ObjectDataInput in) throws IOException { firstName = in.readUTF(); lastName = in.readUTF(); age = in.readInt(); salary = in.readDouble(); address = new Address(); // since Address is DataSerializable let it read its own internal state address.readData (in); } }
As you can see, since
address
field itself
isDataSerializable
, it is calling
address.writeData(out)
when writing and
address.readData(in)
when reading. Also note that the order of writing and reading fields should be the same.
While Hazelcast serializes a DataSerializable it writes the className first and when de-serializes it,
className is used to instantiate the object using reflection.
IdentifiedDataSerializable
To avoid the reflection and long class names
IdentifiedDataSerializable
can be used instead ofDataSerializable
. Note that
IdentifiedDataSerializable
extends
DataSerializable
and introduces two new methods.
IdentifiedDataSerializable uses
getId()
instead of className and uses getFactoryId()
to load the class given the Id.
To complete the implementation a
com.hazelcast.nio.serialization.DataSerializableFactory
should also be implemented and registered into
SerializationConfig
which can be accessed from
Config.getSerializationConfig()
. The Factories responsibility is to return an instance of
the right
IdentifiedDataSerializable
object, given the id. So far this is the most efficient
way of Serialization that Hazelcast supports of the shelf.