java - 使用单例设计模式进行序列化

标签 java serialization deserialization

我在使用单例模式序列化类时遇到问题。首先介绍一下代码:

import java.io.ObjectStreamException;
import java.io.Serializable;

import org.ejml.simple.SimpleMatrix;

public class Operation implements Serializable {

    private static final long serialVersionUID = 1L;

    private final static int CONSTANT = 10;

    private SimpleMatrix data;
    private Long timestamp;

    private static Operation instance = new Operation ();

    private Operation () {
        data = new SimpleMatrix(1, CONSTANT);
    }

    protected static Operation getInstance() {
        return instance;
    }

    //Hook for not breaking the singleton pattern while deserializing.
    private Object readResolve() throws ObjectStreamException {
          return instance;
    }


    protected void setData(SimpleMatrix matrix) {
        this.data = matrix;
    }

    protected SimpleMatrix getData() {
        return data;
    }

    public Long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }
}

我遇到三个问题,希望有人可以帮助我:

  1. 据我所知,静态字段没有序列化。那么,如果我反序列化,我的最终静态字段 CONSTANT 设置为 10 吗?如果没有,我该怎么做?这一点非常重要。

  2. 如您所见,在构造函数中创建了一个新矩阵。如果我反序列化,我的data会被这个构造函数覆盖吗?对于反序列化,我想要序列化版本的数据,而不是新的矩阵。构造函数我只需要在序列化之前第一次实例化对象。

  3. 在序列化之前,我会将字段 timestamp 设置为序列化时间。反序列化后,我想将此字段与某些文件的时间戳进行比较(以查看文件自序列化以来是否已更改)。我应该对文件的序列化时间和最后修改时间使用什么样的时间戳以便我可以轻松进行比较?

最佳答案

  1. 静态常量与类关联,因此实例的序列化和反序列化根本不会影响它。

  2. 为了使反序列化工作,您需要将单例的数据设置为反序列化的实例数据:

    private Object readResolve() throws ObjectStreamException {
        instance.setData(getData());
        return instance;
    }
    
  3. 时间戳可以保留为 Long,这很好。使用 System.currentTimeMillis(),您将能够与 File 对象的 lastModified() 日期进行比较。只需在序列化时设置字段即可:

    private void writeObject(java.io.ObjectOutputStream out)
        throws IOException{
        timestamp=System.currentTimeMillis();
        out.defaultWriteObject();
    }
    

我做了一个测试来确定我所说的,使用字符串而不是代码中的矩阵:

public static void main(String[] args) throws Exception {
    Operation op=getInstance();
    op.setData("test1");
    byte[] ds=serialize();
    System.out.println(new Date(getInstance().timestamp));
    op.setData("test2");
    deserialize(ds);
    System.out.println(getInstance().getData());

}

这给了我当前日期和test1,因为反序列化实例已经覆盖了当前实例。 serializedeserialize 只是在实例和字节之间进行转换。

关于java - 使用单例设计模式进行序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35632581/

相关文章:

java - IntelliJ 说它无法解析 getValue()

c# - 以人类可读的文本格式序列化

android - 在 Android 中序列化/反序列化图像的最佳方式

rust - Rust-使用serde/reqwest “Invalid type”反序列化

c# - 从 MemoryStream 反序列化对象时出错

java - 如果连接 SonicMQ 被拒绝,则重新连接到 SonicMQ

java - 将微小的低分辨率应用程序缩放到更大的屏幕尺寸

java - 如何使用gson序列化Pair的ArrayList

python - 在 Python 中使用换行符序列化 JSON 文件

java - 在实现 Externalizable 时重用 Java(反)序列化