首页 > 解决方案 > 如何序列化类,然后用 Java 中同一类的修改版本读取它们

问题描述

我正在开发一个 Minecraft 插件,它使用我制作的名为 customPlayer 的类。当我从正在运行的实例中保存插件数据时,我将所有这些对象放入 HashMap<String,customPlayer> 并使用 ObjectOutputStream 保存它们。将这些类加载回相同版本的插件效果很好,但是当我修改类并尝试使用修改后的类(通常与我的插件的新版本相关联)读取对象时,我的问题就出现了。

我想了一会儿,认为我想出了一个聪明的解决方案。我的想法是将旧的类文件作为外部库包含在新版本的插件中,交叉手指并希望它有效。它没有。

有一个更好的方法吗?我是序列化和这类东西的新手,所以任何建议都将不胜感激。下面我将包括一些customPlayer类的截图和服务器的崩溃日志。理想情况下,所提出的任何解决方案都应该能够在未来对类进行修改时轻松使用(通过 Github 存储库下载的 Jar 更新)。

customPlayer.java 的实例变量和构造函数

标签: javaserializationminecraft

解决方案


有一个更好的方法吗?

肯定有。停止使用序列化和 ObjectOutputStream。这些类是一场灾难(即使是 OpenJDK 核心团队也有效地同意这种评估)。它们生成的输出不是特别有效(它比需要的字节多),它不是人类可读的,也不是(很容易)被除 java 代码之外的任何东西读取,它会导致你遇到这种毛茸茸的情况。

而是使用例如Jackson将您的对象转换为 JSON,或使用 google 的 protobuf 将其转换为高效的二进制 blob。

你可以用任何你想要的语言阅读这个 JSON 或这些二进制 blob,并且你可以选择图书馆的垃圾。您将需要编写一些显式代码来“保存”一个对象(将其转换为 JSON / protobuf),并“读取”一个对象,但现在您可以自由更改您的代码。

如果坚持要继续序列化,则需要添加一个名为 的字段serialVersionUID,并设置readObjectand writeObject。这是错综复杂的火箭科学,很难做到正确。详细信息java.io.Serializable.

不过,帮自己一个忙。不要这样做


推荐阅读