6

假设我在内存中有一个arr类型的对象数组A,每个对象都有一个指向同一个对象的引用字段B

插图:

A_1  A_2  A_3 ... A_N
 |    |    |       |
 |    |    V       |
 \--->\--> B <-----/

请注意,每个 type 对象中的引用字段都A指向同一个type 对象B

arr现在,我将包含类型对象A的数组序列化为ObjectOutputStream. 然后我反序列化以这种方式获得的字节。

我得到一个新数组arr1

1)数组是否arr1有类型的对象,A使得它们都指向同一个类型的对象B?(我不是指序列化之前的同一个对象,而是新创建的唯一类型的对象B

2) 换句话说,在 Java 中调用 serialize/deserialize 是否保留与序列化之前相同的对象图?(即新反序列化的对象图与旧对象图同构)

3)这在哪里记录?(即请提供引用)

4) 相同的问题 1-3,但适用于 Java 的Kryo序列化框架。

谢谢你。

4

1 回答 1

10

http://docs.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html

对象的默认序列化机制写入对象的类、类签名以及所有非瞬态和非静态字段的值。对其他对象的引用(瞬态或静态字段除外)也会导致这些对象被写入。 对单个对象的多个引用使用引用共享机制进行编码,以便对象的图形可以恢复到与原始对象相同的形状。

至于我对规范的理解,如果要共享的对象实例通过相同的 ObjectOutputStream,您将获得共享对象引用。

因此,当您序列化包含该arr数组的类时,写入的每个对象都会获得一个 ID,并且对于通过流的每个引用,只写入该 ID。在这种情况下,反序列化的图与原始图保持同质。

很抱歉,我对 krio 库自己的序列化机制无能为力,我很乐意向同样使用它的人学习。

关于 kryo 的编辑:

我发现的一些文档:

  • 默认情况下,图形中对象在第一次出现之后的每次出现都存储为整数序数。这允许对同一对象和循环图的多个引用进行序列化。这有少量开销,如果不需要,可以禁用以节省空间:kryo.setReferences(false);

  • 这个(github)是引用解析器的合约;给出了两种实现:基于 ArrayList 的小对象图,基于 Map 的大对象

  • 是默认对象数组(反)序列化器的实现

  • 类需要注册(反)序列化;每个注册的类都可以加上一个序列化器(其中Java默认的序列化机制

于 2012-09-16T12:35:48.557 回答