我创建了一个需要序列化的树数据结构,但每棵树都共享一个公共的根对象,这是一个公共静态最终常量。
我遇到的问题如下图所示。序列化ROOT对象后,反序列化会创建一个新的Tree对象,而不是返回对原始常量的引用。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
public class Main {
public static final class Tree implements Serializable {
public final ArrayList<Tree> branches = new ArrayList<>();
}
public static final Tree ROOT = new Tree();
public static void main(String[] args) throws Exception {
File file = new File("C:/Users/Stephen/Desktop/temp.bin");
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));
oout.writeObject(ROOT);
oout.writeObject(ROOT);
oout.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
Tree t1 = (Tree) oin.readObject();
Tree t2 = (Tree) oin.readObject();
oin.close();
System.out.println(ROOT == t1); // false
System.out.println(t1 == t2); // true
}
}
第一个print语句输出“false”,但我希望它是“true”。
答案 0 :(得分:1)
感谢@yshavit的评论,我能够找到自己问题的答案。诀窍是在反序列化时使用#readResolve()方法。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.util.ArrayList;
public class Main {
public static final class Tree implements Serializable {
public final ArrayList<Tree> branches = new ArrayList<>();
private final boolean isRoot = ROOT == null;
private Object readResolve() throws ObjectStreamException {
if(isRoot)
return ROOT;
else
return this;
}
}
public static final Tree ROOT = new Tree();
public static void main(String[] args) throws Exception {
File file = new File("C:/Users/Stephen/Desktop/temp.bin");
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));
oout.writeObject(ROOT);
oout.writeObject(ROOT);
oout.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));
Tree t1 = (Tree) oin.readObject();
Tree t2 = (Tree) oin.readObject();
oin.close();
System.out.println(ROOT == t1); // true
System.out.println(t1 == t2); // true
}
}
答案 1 :(得分:0)
==
比较内存位置,当且仅当它相同时才认为对象是相等的。话虽如此,Java中的相等性取决于用户。您是否希望将对象视为相等,当且仅当它们是相同的对象(存储在相同的内存位置)或者您是否有一组规则(该对象的哪些属性应相同才能认为对象相等)?
在您的情况下,您需要检查ROOT
和root
对象及其属性内容的内容。==
将始终比较内存位置,并且总是会有所不同不同的对象(在这种情况下为ROOT和root)
答案 2 :(得分:-1)
root == ROOT会不会返回内存位置?您需要比较根ArrayList与ROOT ArrayList
相同