Java 序列化傻瓜书

标签 java serialization io deserialization backwards-compatibility

我仍在处理我已经需要一些帮助的项目: JavaFX - TableView doesn't update items

现在我想了解 Java 中的整个序列化过程是如何工作的,因为不幸的是,我现在还不太明白。

在继续之前,首先,我是一名学生,我不是专业人士。其次,我既不熟悉使用数据库,也不熟悉 XML 或 JSON,所以我只想找到我的方法的解决方案,无论它最终有多不优雅,它只需要工作即可。因此,如果我拒绝任何使用其他技术的建议,请不要感到被冒犯。

这就是我想要的: 将三个不同的类对象保存到单独的文件中,但保持对每个对象的向后兼容性。这些对象是“设置”、“统计”和一个“数据库”对象,其中包含添加到其中的列表中的所有单词。将来我可能会添加更多统计信息或设置,这意味着添加新变量,主要是 IntegerPropertyDoubleProperty 类型。

现在的问题是:是否可以加载旧版本保存的文件,然后在此过程中仅使用 null 启动旧版本中未找到的新变量,但保持其余部分不变保存了吗?

我所知道的是,要做的第一件事就是不要更改serialVersionUID

<小时/>

另一件事是保存整个模型对象(其中包含前面提到的三个对象),所以我只需要为一个类而不是三个类实现一些东西。但是关于向后兼容性,这将如何发挥作用呢?我的意思是类本身不会改变,但它的属性在它们自己的类结构中。

<小时/>

最后,我应该采取什么方法?最重要的是,我该如何做到这一点并同时保持向后兼容性?我最擅长的是一些具体的例子而不是简单的理论。

这里有两个示例方法,如果有帮助的话。我已经为每个类提供了写入和读取对象的方法。

public static void saveModel(Model model, String destination) throws IOException
{
    try 
    {
        fileOutput = new FileOutputStream(destination);
        objectOutput = new ObjectOutputStream(fileOutput);
        objectOutput.writeObject(model);
    }
    catch (IOException e) 
    {
      e.printStackTrace();
    }
    finally
    {
      if (objectOutput != null) 
      try 
      { 
           objectOutput.close(); 
      } 
      catch (IOException e) {}

      if (fileOutput != null) 
      try 
      { 
          fileOutput.close(); 
      } 
      catch (IOException e) {}
    }
}

public static Settings readSettings(String destination) throws IOException, FileNotFoundException
{
    Settings s = null;

    try 
    {
        fileInput = new FileInputStream(destination);
        objectInput = new ObjectInputStream(fileInput);

        Object obj = objectInput.readObject();

        if (obj instanceof Settings) 
        {
            s = (Settings)obj;  
        }
    }
    catch (IOException e) 
    {
        e.printStackTrace();
    }
    catch (ClassNotFoundException e) 
    {
        e.printStackTrace();
    }
    finally 
    {
        if (objectInput != null) try { objectInput.close(); } catch (IOException e) {}
        if (fileInput != null) try { fileInput.close(); } catch (IOException e) {}
    }

    return s;
}

告诉我您是否需要更多我当前的代码。

提前谢谢您!

最佳答案

...你一定有这么高

对于序列化的最佳建议是避免序列化以实现应用程序持久性,特别是如果应用程序中需要向后兼容性。

答案

Is it possible to load old version saved files and then during the process just initiate new variables not found in the old version with just null but keep the rest as it has been saved?

。仅在以下情况下才可以将使用该类的早期版本保存的对象反序列化到该类的新版本中:

  • 类的完全限定名称未更改(名称和包相同)
  • 上一个类和当前类具有完全相同的serialVersionUID;如果其中一个版本缺少它,它将被计算为所有字段和方法的“哈希”和方法,并且一旦不匹配,反序列化就会失败。
  • 该类的继承层次结构没有改变(相同的祖先)
  • 新版本的类中没有删除任何字段
  • 没有字段变为静态
  • 没有字段变得 transient

I just have to implement stuff for one class instead of three. But how would that work then concerning backward compatibility?

。前提是 Model 的所有字段的所有类以及 Model 类本身都遵守上述规则。

Finally, what approach should I go for? And most of all, how do I do this and maintaning backward compatibilty at the same time?

是的,只要你能永远保证上述所有规则,你就会向后兼容。

我相信您会明白,永远,甚至明年都很难保证,尤其是在软件领域。

这就是为什么人们使用更健壮的数据交换格式而不是序列化 Java 对象的二进制表示来进行应用程序持久性。

可以使用从 CSV 文件到存储为文件或 NoSQL 数据库中文档的 JSON 文档的任何内容来保存表的原始数据。

对于设置/配置,请查看 Java 的 Properties 类,它可以在 *.properties*.xml 之间存储和加载属性> 文件或单独查看 YAML

最后为了向后兼容,请查看 FlatBuffers

应用程序持久化领域非常丰富且成熟,所以探索愉快。

关于Java 序列化傻瓜书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42670799/

相关文章:

java读取 float 的字节流

java - 如何处理 Android 上的应用程序从免费版本升级到付费版本

java - com.ibm.db2.jcc.am.io : DB2 SQL Error: SQLCODE=-440, SQLSTATE=42884

java - Java 中的整数缓存

go - 内置库来持久化 BTree,相当于 Java 的 `FileChannel` 和 `ByteBuffer`

c# - 在 C# 中读取包含大量行的文本文件

java - 在 JUnit 4.11 中结合 @ClassRule 和 @Rule

java - 通过 ObjectStream 序列化问题发送/接收

java - java中与序列化相关的方法声明

Python - 如何存储文本文件中的数据而不同时将所有数据存储在主内存中?