【问题标题】:Serializing is not storing object data, only object references序列化不存储对象数据,只存储对象引用
【发布时间】:2009-03-20 17:20:22
【问题描述】:

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

假设每个节点最多可以有 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。

所以我似乎是在序列化对象引用而不是对象本身,有什么想法会出错吗?

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    为我工作,带有 gij 4.3.2 的 GNU/Linux。

    确保 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;
        }
    }
    

    【讨论】:

    • 这让我觉得是其他原因导致了这种情况的发生。我必须深入挖掘谢谢。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 2010-12-09
      • 2012-10-28
      相关资源
      最近更新 更多