反序列化时序列化的公共静态最终对象不= =自身

时间:2018-04-05 04:10:20

标签: java serialization

我创建了一个需要序列化的树数据结构,但每棵树都共享一个公共的根对象,这是一个公共静态最终常量。

我遇到的问题如下图所示。序列化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”。

3 个答案:

答案 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中的

==比较内存位置,当且仅当它相同时才认为对象是相等的。话虽如此,Java中的相等性取决于用户。您是否希望将对象视为相等,当且仅当它们是相同的对象(存储在相同的内存位置)或者您是否有一组规则(该对象的哪些属性应相同才能认为对象相等)?

在您的情况下,您需要检查ROOTroot对象及其属性内容的内容。==将始终比较内存位置,并且总是会有所不同不同的对象(在这种情况下为ROOT和root)

答案 2 :(得分:-1)

root == ROOT会不会返回内存位置?您需要比较根ArrayList与ROOT ArrayList

相同