2.8 序列化:完整版

2.1.3 节列出了实现序列化的五个步骤,到现在为止,我们已经可以借助 Field 对象实现这五个任务了。下面是完整版的 serializeObject 方法的实现,代码依赖 JDOM 库来处理 XML 相关内容。

private static Document serialize(Object source, Document target, IdentityHashMap<Object, Object> table) throws IllegalArgumentException, IllegalAccessException {

  // 1. 创建序列化对象的 唯一标识符
  String id = Integer.toString(table.size());
  table.put(source, id);

  Class sourceClass = source.getClass();

  // 2. 为 source 对象创建 XML 元素,并添加进 root 元素 <serialized /> 中
  Element objElement = new Element("object");
  objElement.setAttribute("class", sourceClass.getName());
  objElement.setAttribute("id", id);

  target.getRootElement().addContent(objElement);

  // 3. 数组需要特殊处理
  if (sourceClass.isArray()) {
    Class componentType = sourceClass.getComponentType();

    int len = Array.getLength(source);
    objElement.setAttribute("length", Integer.toString(len));

    for (int i = 0; i < len; i ++) {
      objElement.addContent(serializeVariable(componentType, Array.get(source, i), target, table));
    }

  } else {
    Field [] fields = Util.getInstanceVariables(source);

    for (Field f : fields) {
      // non public field
      if (! Modifier.isPublic(f.getModifiers())) {
        f.setAccessible(true);
      }

      // 唯一标识符:声明类 + 字段名
      Element fieldEle = new Element("field");
      fieldEle.setAttribute("name", f.getName());
      fieldEle.setAttribute("declaringClass", f.getDeclaringClass().getName());

      Class fieldType = f.getType();
      Object child = f.get(source);

      if (! Modifier.isTransient(f.getModifiers())) {
        child = null;
      }

      fieldEle.addContent(serializeVariable(fieldType, child, target, table));

      objElement.addContent(fieldEle);
    }

  }

  return target;
}

代码解析

  • IdentityHashMap
    • 记录对象 引用次数 需要用 IdentityHashMap,而不能用普通 Map 实现、
    • IdentityHashMap 比较 key 是否相等时,使用 ==,即 key 的引用相等,即认为 key-value 相等,在 JVM 中,若两个 key 引用相同 Class 的对象,则其 引用相等
    • IdentityHashMapkey 可以重复。
  • 代码中用 IdentityHashMap 存储 所有对象 的引用,保证无论 对象被引用多少次,该对象仅序列化一次。

results matching ""

    No results matching ""