Java自动指针调整?

时间:2012-02-29 00:52:33

标签: java serialization deserialization swizzling

假设我们有一个由节点和指针表示的任意图形:

class Node
{
    public ValueType data;
    public ArrayList<Node> adj;
}

现在,我想获取它的副本或在磁盘上写/读它(AKA序列化/反序列化)。我也知道可以使用搜索算法+关联数组来完成。而且,事实证明这种方法称为swizzling

以下是我的问题:

我听说在Java中将类声明为Serializable,这个功能是自动提供的。 (这对我来说听起来像魔术!)

这句话是否正确? Java会自动运行BFS来遍历图表并调整指针吗?换句话说,为我复制/反序列化克隆对象吗? (一个完全全新的对象,具有相同的结构,但新的节点和更新的指针)

如果是,那么如果在某些情况下我只想复制指针呢?如果我想序列化对象只是为了保留原始指针怎么办?

我感谢对此提出任何意见。 : - )

2 个答案:

答案 0 :(得分:1)

我并不认为你是如何思考它的,而是相当多。 Java中的序列化是一个相当不透明的过程。您真正需要知道的是,假设一个类及其成员的所有类型,实现Serializable,Java知道如何将其转换为字节流,以及如何重新创建对象的实例当你要求它反序列化时,从那个流中。

来自C ++,起初看起来确实像黑魔法。我对整个过程持怀疑态度并且并不真正相信JVM会为我照顾它,因为在C ++中,它对于一个普通的对象没有足够的了解来做到这一点。但它实际上非常好,假设您只需要从Java访问数据。

基本上,没有必要担心它下面使用的指针或算法。你只是告诉它写一个对象,然后告诉它读一个对象,你基本上得到了与以前完全相同的内存结构。

还有一件事:如果你将一个变量声明为transient,它就不会被保存,你必须自己恢复它。如果您的字段可以缓存某些您不想浪费空间的值,或者包含您不想要的敏感数据字段,则此功能非常有用。但是你必须记得自己恢复它。

答案 1 :(得分:1)

我先解决你的上一个问题。序列化的目的不是在内存中克隆对象图。它是将对象图转换为字节流,以便执行保存文件或通过线路发送等操作。反序列化过程可能在不同的计算机上,在不同的时间,在不同的进程中,甚至由非Java程序完成,因此不能合理地期望获得与以前相同的对象的引用。正在保存和以后恢复的对象图的结构和内容,而不是内存中的地址。正是由于这个原因,所有对象都可以序列化是没有意义的。例如,序列化Thread不会有用,因为它在程序的当前实例之外没有意义。

自动序列化背后的魔力并不是很复杂。忽略可以为自己的类编写的自定义序列化方法,以精确控制序列化和反序列化行为,是的,系统将有效地遍历对象图以生成字节流。此遍历通常以DFS而非BFS完成。基本上,您要求Java序列化一个对象,并传递对它的引用。该引用将作为对象图的根。从那里,Java将递归序列化该对象的字段。当然,它会跟踪循环引用并在输出流中写出适当的标记,以便解串器能够连接指针并重新创建之前的结构。