Class Serializer

java.lang.Object
com.liferay.petra.io.Serializer

public class Serializer extends Object
Serializes data in a ClassLoader-aware manner.

The Serializer can perform better than ObjectOutputStream and DataOutputStream, with respect to encoding primary types, because it uses a more compact format (containing no BlockHeader) and simpler call stack involving BigEndianCodec, as compared to using an OutputStream wrapper on top of Bits.

For Strings, the UTF encoding for ObjectOutputStream and DataOutputStream has a 2^16=64K length limitation, which is often too restrictive. Serializer has a 2^32=4G String length limitation, which is generally more than enough. For pure ASCII character Strings, the encoding performance is almost the same, if not better, than ObjectOutputStream and DataOutputStream. For Strings containing non-ASCII characters, the Serializer encodes each char to two bytes rather than performing UTF encoding. There is a trade-off between CPU/memory performance and compression rate.

UTF encoding uses more CPU cycles to detect the unicode range for each char and the resulting output is variable length, which increases the memory burden when preparing the decoding buffer. Whereas, encoding each char to two bytes allows for better CPU/memory performance. Although inefficient with compression rates in comparison to UTF encoding, the char to two byte approach significantly simplifies the encoder's logic and the output length is predictably based on the length of the String, so the decoder can manage its decoding buffer efficiently. On average, a system uses more ASCII String scheming than non-ASCII String scheming. In most cases, when all system internal Strings are ASCII Strings and only Strings holding user input information can have non-ASCII characters, this Serializer performs best. In other cases, developers should consider using ObjectOutputStream or DataOutputStream.

For ordinary Objects, all primary type wrappers are encoded to their raw values with one byte type headers. This is much more efficient than ObjectOutputStream's serialization format for primary type wrappers. Strings are output in the same way as writeString(String), but also with one byte type headers. Objects are serialized by a new ObjectOutputStream, so no reference handler can be used across Object serialization. This is done intentionally to isolate each object. The Serializer is highly optimized for serializing primary types, but is not as good as ObjectOutputStream for serializing complex objects.

On object serialization, the Serializer uses the ClassLoaderPool to look up the context name corresponding to the object's ClassLoader. The context name is written to the serialization stream. On object deserialization, the Deserializer uses the ClassLoaderPool to look up the ClassLoader corresponding to the context name read from the deserialization stream. ObjectOutputStream and ObjectInputStream lack these features, making Serializer and Deserializer better choices for ClassLoader-aware Object serialization/deserialization, especially when plugins are involved.

See Also:
  • Constructor Details

    • Serializer

      public Serializer()
  • Method Details

    • toByteBuffer

      public ByteBuffer toByteBuffer()
    • writeBoolean

      public void writeBoolean(boolean b)
    • writeByte

      public void writeByte(byte b)
    • writeChar

      public void writeChar(char c)
    • writeDouble

      public void writeDouble(double d)
    • writeFloat

      public void writeFloat(float f)
    • writeInt

      public void writeInt(int i)
    • writeLong

      public void writeLong(long l)
    • writeObject

      public void writeObject(Serializable serializable)
    • writeShort

      public void writeShort(short s)
    • writeString

      public void writeString(String s)
    • writeTo

      public void writeTo(OutputStream outputStream) throws IOException
      Throws:
      IOException