Home > database >  How to automatically add new variables to files in Java?
How to automatically add new variables to files in Java?

Time:07-05

So I have this class.

public class Player implements Serializable {
    private static final long serialVersionUID = 1L;
    
    public int    health;
    public String name;
}

I load the Player when they "connect", and I save the Player when they "Disconnect". I save and load using the Object Input/Output stream.

Later on, I want to add a gold variable to the Player. So the code will be:

public class Player implements Serializable {
    private static final long serialVersionUID = 1L;
    
    public int    health;
    public String name;
    public int    gold;
}

I still want the file to contain the health and name, but I want to update it with the gold variable; how would I go about doing that? I know I can check if the gold is null, and if so append it to the next save. But is there a way where I can add as many variables as I will, and the code will automatically save the new variables in the class?

Is there a way for the code to automatically add new variables to the file?

Load Player:

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;
}

Save Player:

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;
}

CodePudding user response:

Java is strictly typed. Adding a field at runtime, though possible would take some of the dark arts (modify classes at runtime).

It seems to me you are better off basing your player on HashMap as internal data structure. It can be serialized and deserialized the way you need and allows you to add more values at runtime.

CodePudding user response:

If the contents of your Player class changes only occasionally, you could try the following:

  1. Create a new class containing the new fields, calling it e.g. PlayerV2.
  2. Create a separate program that goes through each of your saved player files. For each file you load the old player object; convert it to a new player object, then save the new player object.
  3. Start using the new player class in your game.

If the player objects are expected to vary a lot over time, and maybe different players will have different contents in their objects, then go with a Map as suggested by the OP.

In this case, you should probably have a version entry in the map. This way you can detect when a player has been saved by an older version of your game, and provide some form of automatic upgrade of the contents of the map, if needed.

CodePudding user response:

Java's built-in object serialization is not very flexible when you need to support different versions. You should change the serialVersionUID of your updated class. But then you won't be able to deserialize older versions. Some possible solutions are:

  1. Define your own readObject and writeObject methods (see Javadoc on ObjectInputStream for details). Then use these to serialize/deserialize a Map of variable names to variable values, using this map as a transfer object to/from your actual class.

  2. Use a different serialization mechanism, such as JSON. Libraries like Jackson are quite flexible in their ability to specify default values for missing fields.

  • Related