Implementing DataSerializable

As mentioned in Implementing Java Serializable & Externalizable, Java serialization is an easy mechanism. However, it does not control how fields are serialized or deserialized. Moreover, Java serialization can lead to excessive CPU loads since it keeps track of objects to handle the cycles and streams class descriptors. These are performance decreasing factors; thus, serialized data may not have an optimal size.

The DataSerializable interface of Hazelcast overcomes these issues. Here is an example of a class implementing the com.hazelcast.nio.serialization.DataSerializable interface.

public class Address implements 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.writeString(street);
        out.writeInt(zipCode);
        out.writeString(city);
        out.writeString(state);
    }

    public void readData( ObjectDataInput in ) throws IOException {
        street = in.readString();
        zipCode = in.readInt();
        city = in.readString();
        state = in.readString();
    }
}

Reading and Writing and DataSerializable

Let’s take a look at another example which encapsulates a DataSerializable field.

Since the address field itself is DataSerializable, it calls address.writeData(out) when writing and address.readData(in) when reading.

public class Employee implements 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.writeString(firstName);
        out.writeString(lastName);
        out.writeInt(age);
        out.writeDouble (salary);
        address.writeData (out);
    }

    public void readData( ObjectDataInput in ) throws IOException {
        firstName = in.readString();
        lastName = in.readString();
        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 the address field itself is DataSerializable, it calls address.writeData(out) when writing and address.readData(in) when reading. Also note that you should have writing and reading of the fields occur in the same order. While Hazelcast serializes a DataSerializable, it writes the className first. When Hazelcast deserializes it, className is used to instantiate the object using reflection.

Since Hazelcast needs to create an instance during the deserialization, DataSerializable class has a no-arg constructor.
DataSerializable is a good option if serialization is only needed for in-cluster communication.
DataSerializable is not supported by non-Java clients as it uses Java reflection. If you need non-Java clients, please use IdentifiedDataSerializable, Portable, or Compact.