折腾GemFire,免不了要折腾序列化和发序列化。GemFire支持Java的序列化,同时也有自己的DataSerializable接口实现自己的序列化,此外还有Delta接口支持数据同步时仅传送上一次数据同步后的更新。 今天测试的实现先用Java的序列化,一开始玩java.io.Serializable接口,后来玩writeObject()和readObject()方法。顺便看看有writeObject方法后ObjectOutputStream调用堆栈与原有分支的不同。
private void writeSerialData(Object obj, ObjectStreamClass desc)
throws IOException {
  ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
  for (int i = 0; i < slots.length; i++) {
    ObjectStreamClass slotDesc = slots[i].desc;
    if (slotDesc.hasWriteObjectMethod()) {
      PutFieldImpl oldPut = curPut;
      curPut = null;
      if (extendedDebugInfo) {
        debugInfoStack.push("custom writeObject data (class \""
            + slotDesc.getName() + "\")");
      }
      SerialCallbackContext oldContext = curContext;
      try {
        curContext = new SerialCallbackContext(obj, slotDesc);
        bout.setBlockDataMode(true);
        slotDesc.invokeWriteObject(obj, this);
        bout.setBlockDataMode(false);
        bout.writeByte(TC_ENDBLOCKDATA);
      } finally {
        curContext.setUsed();
        curContext = oldContext;
        if (extendedDebugInfo) {
          debugInfoStack.pop();
        }
      }
      curPut = oldPut;
    } else {
      defaultWriteFields(obj, slotDesc);
    }
  }
}
Java序列化会写入类描述符,在序列化后的字节数据占一定比例。GemFire支持Java序列化的同时有自己的序列化实现,GemFire自己的序列化实现更高效,而像Hadoop这样的项目则根本不使用Java的序列化,只支持自己的序列化实现。
为了让父类不可序列化的子类序列化,需要父类有public或protected无参构造器,子类需要负责存储和恢复父类的public、protected和(如可访问的)package字段。当父类没有无参构造器,会在运行态序列化子类时返回错误。
下面是Java序列化规范和两个博客连接(这两篇写的都非常细致,后一个一篇都3到5万字,很值得学习)。
Java Object Serialization Specification 
理解Java对象序列化 
Java序列化123