【问题标题】:Java singleton deserialization values keep defaultJava单例反序列化值保持默认
【发布时间】:2014-03-31 09:08:43
【问题描述】:

我有一个简单的单例:

class Test1 implements Serializable {
    private static Test1 instance;

    public String a = "a";
    public String b = "b";
    public String c = null;
    public String d = null;
    public String e;
    public String f;

    private Test1() {
        e = "e";
    }

    public static Test1 getInstance() {
        if (instance == null) {
            instance = new Test1();
        }
        return instance;
    }

    // http://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-with-examples
    protected Object readResolve() {
        return getInstance();
    }

    public String toString() {
        return String.format("Test1{ a:%s, b:%s, c:%s, d:%s, e:%s, f:%s}", a, b, c, d, e, f);
    }
}

我的main()

if ((new File("t1.obj").exists() == false)) {
    Test1 t1 = Test1.getInstance();
    t1.b = "bb";
    t1.d = "dd";
    t1.f = "ff";

    serialize("t1.obj", t1);
}

else {
    Test1 t2 = deserialize("t1.obj");
}

第一次运行看起来不错

Serialized hu.fehergeri13.abptc.server.Test1 object to t1.obj file.
Test1{ a:a, b:bb, c:null, d:dd, e:e, f:ff}

第二次运行后:

Deserialized hu.fehergeri13.abptc.server.Test1 object from t1.obj file.
Test1{ a:a, b:b, c:null, d:null, e:e, f:null}

我的序列化/反序列化:

public static void serialize(String filePath, Object o) {
    try {
        FileOutputStream fos = new FileOutputStream(filePath);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(o);

        System.out.println(String.format("Serialized %s object to %s file.", o.getClass().getName(), filePath));
        oos.close();
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static <T> T deserialize(String filePath) {
    try {
        FileInputStream is = new FileInputStream(filePath);
        ObjectInputStream ois = new ObjectInputStream(is);
        T o = (T) ois.readObject();

        System.out.println(String.format("Deserialized %s object from %s file.", o.getClass().getName(), filePath));
        ois.close();
        is.close();
        return o;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
}

为什么值保持默认而不是bb,dd,ff

【问题讨论】:

  • 您是否在测试之间删除了t1.obj 文件?
  • 你能发布 deserialize() 方法吗?
  • @jeroen_de_schutter 不。在我的实际情况中,我有一个存储约 10MB 数据库的单例。因此,我不是在每次运行时都生成数据库,而是将其序列化并在下次运行后从文件中读取。
  • @anonymous 当然,我更新了我的问题。
  • 我认为 readResolve() 存在问题,这导致您拥有默认实例。也许这会对你有所帮助stackoverflow.com/questions/17387457/…

标签: java serialization singleton default-value


【解决方案1】:

我的可序列化单例:

public class MySingleton implements Serializable {

    private static final long serialVersionUID = -5909418239300111453L;
    private static MySingleton instance = null;

    protected MySingleton() {

    }

    public static MySingleton getInstance() {
        if (instance == null) {
            instance = new MySingleton();
        }
        return instance;
    }

    protected Object readResolve() {
        return getInstance();
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ois.defaultReadObject();
        instance = this;
    }

    private String attr;

    public String getAttr() {
        return attr;
    }

    public void setAttr(String attr) {
        this.attr = attr;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多