虚拟机的Java序列化

虚拟机的Java序列化,java,serialization,io,deserialization,backwards-compatibility,Java,Serialization,Io,Deserialization,Backwards Compatibility,我仍在进行我已经需要一些帮助的项目: 现在我想了解Java中整个序列化过程是如何工作的,因为不幸的是,我现在还不太明白 在我继续之前,首先,我是一名学生,我不是专业人士。其次,我既不熟悉使用DBs,也不熟悉XML或JSON,所以我只想找到我的方法的解决方案,不管它最终有多不雅观,它只需要工作就行了。所以,如果我在使用其他技术时拒绝任何建议,请不要感到生气 所以我想要的是: 将三个不同的类对象保存到单独的文件中,但保持与每个类对象的向后兼容性。这些对象是设置、统计和数据库对象,包含添加到其中的列

我仍在进行我已经需要一些帮助的项目:

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

在我继续之前,首先,我是一名学生,我不是专业人士。其次,我既不熟悉使用DBs,也不熟悉XML或JSON,所以我只想找到我的方法的解决方案,不管它最终有多不雅观,它只需要工作就行了。所以,如果我在使用其他技术时拒绝任何建议,请不要感到生气

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

现在的问题是:是否可以加载旧版本保存的文件,然后在此过程中仅启动旧版本中未找到的新变量(仅为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;
}
如果您需要更多我当前的代码,请告诉我

提前谢谢你

。。。你一定有这么高 序列化的最佳建议是为了应用程序持久性而避免序列化,特别是在应用程序中需要向后兼容的情况下

答案 是否可以加载旧版本保存的文件,然后在此过程中仅启动旧版本中未找到的新变量(仅为null),但将其余变量保持为已保存状态

对。仅当满足以下条件时,才能将使用类的早期版本保存的对象反序列化到此类的新版本中:

类的完全限定名未更改相同的名称和包 前一个类和当前类具有完全相同的serialVersionUID;如果其中一个版本缺少它,它将被计算为所有字段和方法的“哈希”,并且在不匹配时反序列化将失败。 相同祖先的类的继承层次结构没有更改 新版本的类中未删除任何字段 没有字段是静态的 没有一个磁场是瞬变的 我只需要为一个类而不是三个类实现一些东西。但是,关于向后兼容性,这将如何工作呢

对。提供模型所有字段的所有类以及模型类本身遵守上述规则

最后,我应该采取什么方法?最重要的是,我如何做到这一点,同时保持向后兼容性

是的,只要您能够永远保证上述所有规则,您就可以向后兼容

我相信你们会明白,永远,甚至明年都很难保证,特别是在软件方面

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

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

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

最后,关于向后兼容性,请查看


应用程序持久性领域非常丰富和成熟,所以很乐意探索。

在编写之前,您是否关闭了流程?那会在你脸上爆炸。然后:你写模型,你读设置?那怎么行?除此之外:为了保存设置,还有一些文件,或者您也可以使用XML。我不会为此使用二进制序列化。垃圾箱不是人类可读的。XML或Propertyfiles将允许您在一个简单的文本编辑器中查看明文中的设置。向后兼容性也更容易做到。这只是两个示例方法,一个用于编写,另一个用于读取,我已经为每个类提供了方法。而且这些设置实际上不应该是可读的,因为我仍然需要序列化其他数据,所以我可以用同样的方法使用这些设置。另外,我没有使用XML的经验
例如,我建议大家都使用DB。我想,二进制序列化会把您引入死胡同。为什么不使用json、xml或db而不是序列化呢?