序列化不存储对象数据,仅存储对象引用

时间:2009-03-20 17:20:23

标签: java serialization

我有一个由Node对象构建的节点树。 它们比我展示的代码更复杂,但只有原始或Serializable实例成员。

假设每个节点最多可以有10个子节点,代码看起来有点像。

public class Node implements Serializable{

    private static final long serialVersionUID = -848926218090221003L;

private Node _parent;
private boolean _hasParent;
private Node[] _children;
private int _childCount = 0;

public Node(Node parent){

    _children = new Node[10];
    _parent = parent;
    _hasParent = (parent != null);
}


    ...

    //Various accessors etc

}

现在这个树的构建成本非常高,但是一旦完成,我就把它写到一个文件中:

ObjectOutputStream serializedOuput = new ObjectOutputStream(new FileOutputStream(cacheFile));
serializedOuput.writeObject(tree);
serializedOuput.close();

当我完成缓存树时,我做了一些不可逆转的修改,就像修剪掉不需要的树枝一样。

然后当我接下来需要一个基础树来工作时,我通过读取我的序列化文件来创建一个新的树对象。

问题......

从文件创建树似乎只是创建一个指向旧对象的新对象。换句话说,写入文件后所做的修改也已经对新树进行了修改。

如果我重新启动应用程序并尝试读取序列化文件,则返回null。

所以我似乎在序列化对象引用而不是对象本身,任何我出错的想法?​​

2 个答案:

答案 0 :(得分:2)

适用于我,GNU / Linux with gij 4.3.2。

确保Node类中的所有字段都是可序列化的。

这是我尝试的代码(应该等同于你的代码):

import java.io.*;

public class TestCase {
    public static void main(String[] args) {
        try {
            if (args.length > 0 && args[0].equals("read")) {
                ObjectInputStream ois = new ObjectInputStream(
                        new FileInputStream("File.log")
                    );
                Node root = (Node) ois.readObject();
                ois.close();

                System.out.println("Root value: " + root.getValue());
                for(Node n : root.children())
                    System.out.println("Child: " + n.getValue());

                return;
            }

            Node root = new Node(null, "First");
            root.add(
                    new Node(root, "Second.Child.1"),
                    new Node(root, "Second.Child.2")
                );

            ObjectOutputStream oos = new ObjectOutputStream(
                    new FileOutputStream("File.log")
                );
            oos.writeObject(root);
            oos.close();
        } catch(Exception e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
        }
    }
}

class Node implements Serializable {
    private static final long serialVersionUID = 2304728943L;
    private Node _parent;
    private Node[] _children;
    private String _value;

    public Node(Node parent, String value) {
        this._parent = parent;
        this._value = value;
        this._children = new Node[2];
    }
    public void add(Node child, Node child2) {
        this._children[0] = child;
        this._children[1] = child2;
    }
    public String getValue() {
        return this._value;
    }
    public Node[] children() {
        return this._children;
    }
    public Node parent() {
        return this._parent;
    }
}

答案 1 :(得分:1)

您可能正在做的一件事是序列化对象,更改它然后将其序列化到同一个流。您将需要重置流,否则处理非分层结构的逻辑将忽略您的更改。其他可能性是静态/单例或奇怪的readResolve使用。