我有一个由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。
所以我似乎在序列化对象引用而不是对象本身,任何我出错的想法?
答案 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使用。