如何在Java中自动添加新变量到文件?



我有了这个类。

public class Player implements Serializable {
private static final long serialVersionUID = 1L;

public int    health;
public String name;
}

当他们"连接"时加载播放器,当他们"断开连接"时保存播放器。我使用对象输入/输出流保存和加载。

之后,我想给玩家添加一个黄金变量。所以代码是:

public class Player implements Serializable {
private static final long serialVersionUID = 1L;

public int    health;
public String name;
public int    gold;
}

我仍然希望文件包含健康和名称,但我想用gold变量更新它;我该怎么做呢?我知道我可以检查金币是否为空,如果是,将其附加到下一个保存中。但是,是否有一种方法可以让我添加尽可能多的变量,并且代码会自动将新变量保存在类中?

是否有一种方法为代码自动添加新的变量到文件?

加载播放器:

try {
final FileInputStream   fileInputStream   = new FileInputStream(file);
final ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
try {
user = (User) objectInputStream.readObject();
} catch (ClassNotFoundException exception) {
exception.printStackTrace();
return false;
}
objectInputStream.close();
fileInputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
return false;
}

保存玩家:

try {
final FileOutputStream   fileOutputStream   = new FileOutputStream(file);
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(user);
objectOutputStream .close();
fileOutputStream.close();
} catch (IOException exception) {
exception.printStackTrace();
return false;
}

Java是严格类型的。在运行时添加一个字段,虽然可能需要一些黑魔法(在运行时修改类)。

在我看来,你最好把你的播放器放在HashMap上作为内部数据结构。它可以按你需要的方式序列化和反序列化,并允许你在运行时添加更多的值。

当您需要支持不同的版本时,Java的内置对象序列化不是很灵活。您应该更改已更新类的serialVersionUID。但是这样就不能反序列化旧版本了。一些可能的解决方案如下:

  1. 定义自己的readObjectwriteObject方法(详见Javadoc上的ObjectInputStream)。然后使用这些来序列化/反序列化变量名到变量值的映射,使用该映射作为到实际类的传输对象。

  2. 使用不同的序列化机制,例如JSON。像Jackson这样的库在为缺失字段指定默认值方面非常灵活。

如果你的Player类的内容只是偶尔改变,你可以尝试以下操作:

  1. 创建一个包含新字段的新类,例如PlayerV2。
  2. 创建一个单独的程序,通过每个保存的播放器文件。对于每个文件,你加载旧播放器对象;将其转换为一个新的播放器对象,然后保存新播放器对象。
  3. 开始在游戏中使用新的玩家类。

如果玩家对象随着时间的推移会有很大的变化,也许不同的玩家在他们的对象中会有不同的内容,那么就按照op的建议使用地图。

在这种情况下,您应该在映射中有一个版本条目。这样你就可以检测到玩家是否被旧版本的游戏保存,并在需要时提供某种形式的地图内容自动升级。

或者,您应该考虑保存为基于文本的格式,如JSON。这样,您的保存文件就不会像使用Java序列化时那样直接绑定到Java类。此外,它将更容易调试,更容易制作直接处理保存文件的工具。

最新更新