2.8.1 序列化所有组件
serialize 方法在每个需要序列化的对象上 递归调用,该方法会创建需要的 XML 文件、填充 引用表,并且用对象的内容来填充 XML 文件,下面是一些细节讨论:
对象引用表
String id = Integer.toString(table.size());
table.put(source, id);
- 为序列化对象创建一个 唯一标识符,这里使用引用表的大小
table.size()作为对象的唯一标识符(why?)。 - 使用序列化对象作为
key,对象的唯一标识符作为value,存入引用表table中。 - 若已存入
table的对象 再次遇到,可根据 对象key轻易查询到其 唯一标识符,因为对象的 序列化版本 已经存入 XML 文件中,所以对象key(实际为对象引用)可被替换为对象的 唯一标识符,从而 每个对象 只有 一个 XML 副本 存在。
对象 -> XML 元素
Class sourceClass = source.getClass();
Element objElement = new Element("object");
// 对象 `Class` 名字
objElement.setAttribute("class", sourceClass.getName());
// 对象唯一标识符
objElement.setAttribute("id", id);
target.getRootElement().addContent(objElement);
- 每个对象 对应一个 XML 元素。
- 将对象的
Class名字和唯一标识符作为元素属性存储。 serialize(source, new Document(new Element("serialized")), new IdentityHashMap<Object, String> table),在serialize方法最初的调用参数中,source作为 初始序列化对象,通过在每个组件对象上 递归 调用serialize方法,每个对象最后都有一个 对应的 XML 文件。
字段 -> XML 元素
// 获取对象所有 实例字段(non-static)
Field[] fields = Util.getInstanceVariables(source);
for (Field f : fields) {
// 设置 non-public 字段的访问权限
if (! Modifier.isPublic(f.getModifiers())) {
f.setAccessible(true);
}
// 字段 -> XML 元素
Element fieldElement = new Element("field");
// 字段名
fieldElement.setAttribute("name", field.getName());
// 声明类
fieldElement.setAttribute("declaringClass", field.getDeclaringClass().getName());
Class fieldType = f.getType(); // 字段类型
Object fieldValue = f.get(source); // 字段值
// transient 字段无需序列化
if (Modifier.isTransient(field.getModifiers())) {
fieldValue = null;
}
fieldElement.addContent(serializeVariable(fieldType, fieldValue, target, table));
objElement.addContent(fieldElement);
}
- 每个字段 对应一个 XML 元素。
transient修饰符表示该字段 不需要 序列化。
数组
Class componentClass = sourceClass.getComponentClass();
int length = Array.getLength(componentClass);
objElement.setAttribute("length", Integer.toString(length));
for (int i = 0; i < length; i++) {
// 添加每个数组元素对应的 XML 元素
objElement.addContent(serializeVariable(componentClass,
Array.get(source, i),
target,
table));
}
- 数组只需要遍历数组元素,将所有元素对应的 XML 元素添加到数组对象的 XML 元素即可。
Array统一了 原始类型数组 和 对象数组 的处理方式,从而在程序中无需关系数组元素的具体类型。